<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>http://steakwiki.com/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Adminguy</id>
	<title>Steak Wiki - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="http://steakwiki.com/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Adminguy"/>
	<link rel="alternate" type="text/html" href="http://steakwiki.com/index.php/Special:Contributions/Adminguy"/>
	<updated>2026-05-29T17:15:47Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.35.1</generator>
	<entry>
		<id>http://steakwiki.com/index.php?title=Docker&amp;diff=1010</id>
		<title>Docker</title>
		<link rel="alternate" type="text/html" href="http://steakwiki.com/index.php?title=Docker&amp;diff=1010"/>
		<updated>2021-09-13T16:26:08Z</updated>

		<summary type="html">&lt;p&gt;Adminguy: /* Installing Docker-compose from pip or github binary not Debian */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;small&amp;gt;Docker is a type of virtualization for Gnu\Linux that allows programs to run and share similar resources, without having a full OS for each image, but while still isolating each 'vm'.&lt;br /&gt;
&lt;br /&gt;
==General Tips==&lt;br /&gt;
It helps to read a book, and then keep it as a Reference. Here Using Docker By Adrian Mouat is a decent book. In fact, you should be reading books on any subject that interests you. Physical paper books, too.&lt;br /&gt;
&lt;br /&gt;
Docker is x86_64. ARM has a separate build. There is no i386.&lt;br /&gt;
&lt;br /&gt;
You will want 'some' RAM. I had 1GB on a P4 machine, and that was not enough. 4GB was enough. &lt;br /&gt;
&lt;br /&gt;
You should always use docker compose. Docker is possible to run on the command line, but with a compose file, you can write everything down in a much simpler fashion. Use compose. It's a separate install, currently. Install it. ''Seriously, just ignore the docker command lines. I consider them useless. More of a red herring for rookies.''&lt;br /&gt;
&lt;br /&gt;
===ARM is SOL===&lt;br /&gt;
I tried to use Docker on ARM, and while you might be able to install docker, you will find that images for your applications may not be there. e.g. you will find Nginx, but you won't find Gitlab. This means that docker is pretty much x86-64 only. (exception: if you make custom Dockerfiles).&lt;br /&gt;
&lt;br /&gt;
==Docker Commands==&lt;br /&gt;
Here are commands you need to know. Just the necessary ones.&lt;br /&gt;
{{cmd| docker-compose up -d}} &lt;br /&gt;
 &lt;br /&gt;
Starts the containers in the docker compose file, if they aren't already started. the -d detaches from the stdout logging. You don't need to use stdout logging, you can use docker logs, but its there if you want it.&lt;br /&gt;
 {{cmd| docker ps }}&lt;br /&gt;
Lists containers running. If one fails to start, you'll see it missing from here&lt;br /&gt;
 {{cmd|docker logs &amp;lt;containername&amp;gt; }}&lt;br /&gt;
Gives you some logging output from the container. Often enough to troubleshoot. (also see tips below).&lt;br /&gt;
 {{cmd|docker exec -it &amp;lt;containername&amp;gt; /bin/bash}}&lt;br /&gt;
This will get you in a shell in the docker container. From here you can do what you need to. Most are debian, and need apt-get install less nano or whatever program you are missing. Ping is missing from possibly all containers, so if you want to test via ping, you'll have to apt-get it.&lt;br /&gt;
 {{cmd|docker-compose restart }}&lt;br /&gt;
This will restart all containers. However, I don't recommend it. Initting containers can get corrupted this way, and also its much easier to restart a single faulty container via...&lt;br /&gt;
 {{cmd|docker restart &amp;lt;containername&amp;gt; }}&lt;br /&gt;
This will restart one single container.&lt;br /&gt;
 {{cmd|docker cp &amp;lt;containername&amp;gt;:/dir/to/file dest }}&lt;br /&gt;
You can copy files from local machine to docker, or vice versa with this. Extremely useful.&lt;br /&gt;
&lt;br /&gt;
===Deleting Containers===&lt;br /&gt;
Less often, you might want to know &lt;br /&gt;
{{cmd|&lt;br /&gt;
 #!/bin/bash&lt;br /&gt;
 docker rm $(docker ps -a -q)&lt;br /&gt;
 docker rmi $(docker images -q) --force}}&lt;br /&gt;
&lt;br /&gt;
This starts over from scratch. This is how easy it is to reboot a docker from square one.  note: below command (rmi), only needed if you want to remove base images. Needed when updating a stable. Not needed when changing other parameters not related to base image. Also, this deletes all containers, which maybe you don't want to do, if you either A) only want to delete certain images you are testing B) have some containers with custom changes saved, and not backed up elsewhere.&lt;br /&gt;
&lt;br /&gt;
===Updating===&lt;br /&gt;
 docker images&lt;br /&gt;
 (shows out of date image)&lt;br /&gt;
 docker pull mysql&lt;br /&gt;
 (downloads new image)&lt;br /&gt;
 docker images&lt;br /&gt;
 (shows two versions of mysql. old and new)&lt;br /&gt;
 docker stop some_container_name&lt;br /&gt;
 docker rmi -f cjklfs23404&lt;br /&gt;
 (where cjklfs23404 is the old container alias under docker images)&lt;br /&gt;
 docker-compose up -d mysql&lt;br /&gt;
&lt;br /&gt;
====Containers don't all Restart?!====&lt;br /&gt;
Make sure to have in your docker compose for each container a '''restart:always'''&lt;br /&gt;
Otherwise, a container won't necessarily start when docker is restarted.&lt;br /&gt;
&lt;br /&gt;
===Search for images===&lt;br /&gt;
 docker search &amp;lt;imagename&amp;gt;&lt;br /&gt;
====Search for Versions of an image====&lt;br /&gt;
What if you want to see what versions are available for a given image? Say you want php, but don't know which to get. hub.docker.com is broken. Requires js, slow, and bad. You can't get a list of images on it easily. &lt;br /&gt;
&lt;br /&gt;
Solution:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
#https://stackoverflow.com/questions/28320134/how-can-i-list-all-tags-for-a-docker-image-on-a-remote-registry&lt;br /&gt;
#$1 means&lt;br /&gt;
#first parameter you pass to this script will be searched&lt;br /&gt;
#e.g. working: debian&lt;br /&gt;
#note: some have multiple layers&lt;br /&gt;
#e.g. gitea/gitea is literally entered as $1 == gitea/gitea  (teste, working)&lt;br /&gt;
# while debian is just debian. so be aware.&lt;br /&gt;
&lt;br /&gt;
wget -q https://registry.hub.docker.com/v1/repositories/$1/tags -O -  \&lt;br /&gt;
| sed -e 's/[][]//g' -e 's/&amp;quot;//g' -e 's/ //g' | tr '}' '\n'  | awk -F: '{print $3}'&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Ref: https://stackoverflow.com/questions/54418542/dockerhub-listing-all-available-versions-of-a-given-image&lt;br /&gt;
&lt;br /&gt;
https://stackoverflow.com/questions/28320134/how-can-i-list-all-tags-for-a-docker-image-on-a-remote-registry&lt;br /&gt;
&lt;br /&gt;
===Save Changes to Docker Image===&lt;br /&gt;
 docker commit&lt;br /&gt;
See official documentation.&lt;br /&gt;
&lt;br /&gt;
===Set IP Address on docker-compose===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 mariadb:&lt;br /&gt;
    image: mariadb:10&lt;br /&gt;
    container_name: mariadb&lt;br /&gt;
    command:&lt;br /&gt;
       - mysqld&lt;br /&gt;
       - --character-set-server=utf8&lt;br /&gt;
       - --collation-server=utf8_bin&lt;br /&gt;
    environment:&lt;br /&gt;
      - MYSQL_ROOT_PASSWORD=admin&lt;br /&gt;
      - MARIADB_DATABASE=guy&lt;br /&gt;
      - MARIADB_USER=user&lt;br /&gt;
      - MARIADB_PASSWORD=passwd&lt;br /&gt;
    volumes:&lt;br /&gt;
      - ./mariadb/appdata:/var/lib/mysql&lt;br /&gt;
      - ./mariadb/config:/etc/mysql&lt;br /&gt;
    networks:&lt;br /&gt;
      somenamefornetwork:&lt;br /&gt;
        ipv4_address: 192.168.12.11&lt;br /&gt;
    ports:&lt;br /&gt;
      - &amp;quot;10055:3306&amp;quot;&lt;br /&gt;
&lt;br /&gt;
networks:&lt;br /&gt;
  somenamefornetwork:&lt;br /&gt;
    ipam:&lt;br /&gt;
      driver: default&lt;br /&gt;
      config:&lt;br /&gt;
        - subnet: &amp;quot;192.168.12.0/24&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Add the networks section to each container.&lt;br /&gt;
&lt;br /&gt;
===Store /var/lib/docker somewhere else===&lt;br /&gt;
i.e. instead of /var/lib/docker put them on external storage...&lt;br /&gt;
Ubuntu/Debian: edit your /etc/default/docker file with the -g option: &lt;br /&gt;
 DOCKER_OPTS=&amp;quot;-dns 8.8.8.8 -dns 8.8.4.4 -g /mnt&amp;quot;&lt;br /&gt;
ref: https://forums.docker.com/t/how-do-i-change-the-docker-image-installation-directory/1169&lt;br /&gt;
&lt;br /&gt;
then &lt;br /&gt;
 stop docker compose&lt;br /&gt;
 stop docker service&lt;br /&gt;
 start docker service&lt;br /&gt;
 start docker compose&lt;br /&gt;
&lt;br /&gt;
the above guide also mentions using a symlink. (that's) A different approach. either should work. This is useful e.g. if you are on a VPS/SBC with limited storage (but have external storage).&lt;br /&gt;
&lt;br /&gt;
==Dockerfile==&lt;br /&gt;
Dockerfiles and compose are slightly confusing. Sometimes you see images run an entrypoint script, sometimes not. In any case, Dockerfiles are fundamental to reproducible builds.&lt;br /&gt;
&lt;br /&gt;
Basic usage is:&lt;br /&gt;
* Docker-compose builds container from dockerfile (say you start with alpine, and install some programs)&lt;br /&gt;
* that container you built is used from thence on. &lt;br /&gt;
* if you want to change dockerfile, make changes and you must call docker-compose up --build otherwise, it will use the old container&lt;br /&gt;
&lt;br /&gt;
For a basic apache server, you might call the following in a cmd at the end of the dockerfile:&lt;br /&gt;
 CMD [&amp;quot;/usr/sbin/apache2&amp;quot;, &amp;quot;-D&amp;quot;, &amp;quot;FOREGROUND&amp;quot;]&lt;br /&gt;
When in doubt, work off of existing examples.&lt;br /&gt;
&lt;br /&gt;
==Volumes==&lt;br /&gt;
Volumes can be handled at least two ways. The simplest is to store files in a local directory which is then mapped to the remote drive.&lt;br /&gt;
&lt;br /&gt;
e.g. docker-compose:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  nginx:&lt;br /&gt;
    image: nginx:####&lt;br /&gt;
    container_name: mynginxserver&lt;br /&gt;
    volumes:&lt;br /&gt;
      - ./nginx.conf:/etc/nginx/nginx.conf&lt;br /&gt;
      - /etc/letsencrypt/:/etc/letsencrypt/&lt;br /&gt;
      - ./local_dir/:/var/www/html/&lt;br /&gt;
      - ./local_logs/:/var/log/nginx/&lt;br /&gt;
    ports:&lt;br /&gt;
      - 80:80&lt;br /&gt;
      - 443:443&lt;br /&gt;
    restart: always&lt;br /&gt;
    logging:&lt;br /&gt;
      driver: &amp;quot;json-file&amp;quot;&lt;br /&gt;
      options:&lt;br /&gt;
        max-size: &amp;quot;200k&amp;quot;&lt;br /&gt;
        max-file: &amp;quot;10&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Here, in the local dir where docker-compose is run, the ./local_dir/ or ./local_logs will store the containers html or logs respectively. Simple. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
However, if you just have a volume, without a local directory, then it will save in /var/ somewhere (unintuitive... bad).&lt;br /&gt;
e.g. from Dolibarr:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
The Dolibarr installation and all data beyond what lives in the database&lt;br /&gt;
 (file uploads, etc) are stored in the unnamed docker volume volume&lt;br /&gt;
/var/www/html and /var/www/documents. The docker daemon will store&lt;br /&gt;
 that data within the docker directory /var/lib/docker/volumes/....&lt;br /&gt;
That means your data is saved even if the container crashes, is stopped&lt;br /&gt;
or deleted.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Specific Tips==&lt;br /&gt;
===YAML is space sensitive===&lt;br /&gt;
When you edit the .yml file for docker-compose, you have to hit spaces in a certain pattern (tabs not allowed). This is absurd, but just be aware. The errors are cryptic, and its often just because the spacing doesn't stick to what it expects.&lt;br /&gt;
===If you restart a containers namesake process, it will probably restart / reset the container===&lt;br /&gt;
So if you are troubleshooting an apache container, you edit some files, then /etc/init.d/apache2 restart, uh oh... You just undid all the edits you made, if they aren't in a permanent volume. You can shell in, make edits, and then exit the shell, but a service restart often resets the container.&lt;br /&gt;
===Consider a single reverse proxy, to handle multiple websites===&lt;br /&gt;
There are many ways to do this. I use an nginx proxy from scratch. You can also use some containers that are built for this purpose (I personally think it's bloated but a lot of people use Jason Wilder's proxy)&lt;br /&gt;
https://web.archive.org/web/https://github.com/jwilder/nginx-proxy - A lot of people swear by this, but I think it's straying too far to the high level.&lt;br /&gt;
===If you use a single reverse proxy, Lets Encrypt can be done easy===&lt;br /&gt;
In this case scenario you would have certbot on the host and a local volume that the proxy has access to which is the webroot of the Lets Encrypt scripts. The nginx proxy entry look something like this:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
location ^~ /.well-known {&lt;br /&gt;
     alias /var/www/html/.well-known/;&lt;br /&gt;
      autoindex on;&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
And this is put in every server declaration of nginx.conf. Real simple, real easy. The docker compose of the nginx proxy is something like:&lt;br /&gt;
&lt;br /&gt;
{{cat|docker-compose.yml|&lt;br /&gt;
nginx:&lt;br /&gt;
    image: nginx:latest&lt;br /&gt;
    container_name: custom_name_for_my_proxy&lt;br /&gt;
    volumes:&lt;br /&gt;
      - ./nginx.conf:/etc/nginx/nginx.conf&lt;br /&gt;
      - /etc/letsencrypt/:/etc/letsencrypt/&lt;br /&gt;
      - ./webroot/:/var/www/html/&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
The volumes section is extremely simple, don't be scared. There are two entries. Local and remote. You specify what folder will be the local directory which will be cloned to the host at the remote path you specify. So, the host runs certbot at /etc/letsencrypt, and this folder is cloned to the nginx proxy container, at the same location. Finally, webroot must be set in certbot, but it prompts you for this. And if you forget or get it wrong, it can be configured somewhere in /etc/letsencrypt. it's a one liner text entry).&lt;br /&gt;
&lt;br /&gt;
===Give every Container a Containername===&lt;br /&gt;
This makes it easier to refer to them later. All you need to do in the compose file is include container\_name: something. Much better than the gibberish they give these names if you don't include it.&lt;br /&gt;
===Beware of Interrupting Initting Containers===&lt;br /&gt;
When you first build a container, it might take 30-60 or more seconds to do whatever it needs to do. If, before then, you restart it... It may get corrupted. This has happened to me more than once. When you are testing a new container, and it doesn't seem to work for some inexplicable reason, create a container with a new name (it will create a new one), or delete the first one, and start it again.&lt;br /&gt;
===Put Apache or Program logs from the Container in a volume that is locally accessible===&lt;br /&gt;
This means you want a volume something like ./containerA\_files/logs:/var/www/log/apache2/ so that you can monitor the logs from your host machine easily. docker logs doesn't have everything.&lt;br /&gt;
===Only Restart Containers you need to Restart===&lt;br /&gt;
You can restart everything with docker-compose restart, but it's faster, and less prone to break initting containers, if you docker restart containername. Do the latter.&lt;br /&gt;
===Volumes Mounting Over Existing Directories===&lt;br /&gt;
As discussed here: https://web.archive.org/web/https://github.com/moby/moby/issues/4361, if you add a volume to an existing container, it will seem to delete the folder's contents. I've seen mixed behaviour with this. Sometimes it deletes it even if you start a new container with the folder... Other times it has not. In any case, just docker cp the files to the folder, then add the volume mount. This may not be the most graceful solution for upgrades, but it will work. Best practices would be here (See: dbxt commented Dec 14, 2014): https://web.archive.org/web/https://github.com/docker-library/wordpress/issues/10&lt;br /&gt;
===If you edit a docker-compose file you must restart the container with Docker-compose===&lt;br /&gt;
If you make a change in docker compose, you must docker stop service, then docker-compose up -d service. Otherwise the changes will not take effect. The mistake here, would be thinking that you could just docker stop service, then docker start service... That doesn't work.&lt;br /&gt;
===Keep verbose logging off your HDD with RAM only logging===&lt;br /&gt;
If you have e.g. apache/nginx write to your HDD with every website visit, it will quickly wear out your HDD (esp. SSD). Put verbose logging in the RAM only with a tmpfs mount. https://docs.docker.com/storage/tmpfs/&lt;br /&gt;
&lt;br /&gt;
e.g. (ref: https://stackoverflow.com/questions/41902930/docker-compose-tmpfs-not-working)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
services:&lt;br /&gt;
  ubuntu:&lt;br /&gt;
    image: ubuntu&lt;br /&gt;
    command: &amp;quot;bash -c 'mount'&amp;quot;&lt;br /&gt;
    volumes:&lt;br /&gt;
      - cache_vol:/var/cache&lt;br /&gt;
      - run_vol:/run&lt;br /&gt;
&lt;br /&gt;
volumes:&lt;br /&gt;
  run_vol:&lt;br /&gt;
    driver_opts:&lt;br /&gt;
      type: tmpfs&lt;br /&gt;
      device: tmpfs&lt;br /&gt;
  cache_vol:&lt;br /&gt;
    driver_opts:&lt;br /&gt;
      type: tmpfs&lt;br /&gt;
      device: tmpfs&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This also allows you to share the tmpfs mounts if needed.&lt;br /&gt;
&lt;br /&gt;
Access it from host via:&lt;br /&gt;
 docker exec -it nginx_server tail -F /run/shm/access.log&lt;br /&gt;
Note that you might think you can do&lt;br /&gt;
 docker container run my_nginx_server tail -F /run/shm/access.log&lt;br /&gt;
But that will only work on container base images, not running containers. To 'execute' a command on a running or existing container, the command you want is exec. (Also used to interactively start bash shell above)&lt;br /&gt;
&lt;br /&gt;
EDIT: Use with discretion. Active data in RAM may use power.&lt;br /&gt;
&lt;br /&gt;
===Mysql Backup / Restore===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# Backup&lt;br /&gt;
docker exec CONTAINER /usr/bin/mysqldump -u root --password=root DATABASE &amp;gt; backup.sql&lt;br /&gt;
&lt;br /&gt;
# Restore&lt;br /&gt;
cat backup.sql | docker exec -i CONTAINER /usr/bin/mysql -u root --password=root DATABASE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
ref: https://gist.github.com/spalladino/6d981f7b33f6e0afe6bb&lt;br /&gt;
May not need to do this, if you keep the DB (ibdata files) in a local directory/volume via docker-compose.yml&lt;br /&gt;
e.g.&lt;br /&gt;
 mydb:&lt;br /&gt;
    image: mysql:9999&lt;br /&gt;
    volumes:&lt;br /&gt;
       - ./db_files:/var/lib/mysql&lt;br /&gt;
    restart: always&lt;br /&gt;
&lt;br /&gt;
===Limit docker logs===&lt;br /&gt;
Docker will keep lots of logs if you don't manage it.&lt;br /&gt;
https://github.com/docker/compose/issues/1083&lt;br /&gt;
https://docs.docker.com/compose/compose-file/#logging&lt;br /&gt;
https://stackoverflow.com/questions/31829587/docker-container-logs-taking-all-my-disk-space&lt;br /&gt;
view (all) logs with &lt;br /&gt;
 docker-compose logs&lt;br /&gt;
To limit a service's logs in docker-compose do the following:&lt;br /&gt;
* find a containers/services entry&lt;br /&gt;
* append to the end (watch the white space &amp;amp; no tabs)&lt;br /&gt;
     logging:&lt;br /&gt;
       driver: &amp;quot;json-file&amp;quot;&lt;br /&gt;
       options:&lt;br /&gt;
         max-size: &amp;quot;200k&amp;quot;&lt;br /&gt;
         max-file: &amp;quot;10&amp;quot;&lt;br /&gt;
The rule with logs, is nothing - unless you need it. Then everything. Any unnecessary logging is taxing the CPU / HDD.&lt;br /&gt;
Which leads me to...&lt;br /&gt;
&lt;br /&gt;
===view details about container===&lt;br /&gt;
To view paths, configuration settings, etc...&lt;br /&gt;
See&lt;br /&gt;
 docker inspect &amp;lt;name or id&amp;gt;&lt;br /&gt;
It's easier to grep these. the search in less wasn't working for me to find .LogPath for example.&lt;br /&gt;
 docker inspect mycontainer | grep log&lt;br /&gt;
Will show where the log files are located.&lt;br /&gt;
&lt;br /&gt;
===Installing Docker-compose from pip or github binary not Debian===&lt;br /&gt;
Subject. See official docker documentation which states the URL of&lt;br /&gt;
github.com/docker/compose/releases or pip.&lt;br /&gt;
&lt;br /&gt;
Pip is probably better.&lt;br /&gt;
 apt-get install python3-pip &lt;br /&gt;
 pip3 install docker-compose&lt;br /&gt;
&lt;br /&gt;
===Root on Alpine Images===&lt;br /&gt;
Alpine images: can't su to root.&lt;br /&gt;
su: must be suid to work properly&lt;br /&gt;
use the flag --user root when entering the container.&lt;br /&gt;
&lt;br /&gt;
 docker exec -it --user root mycontainername bash     &lt;br /&gt;
&lt;br /&gt;
And alpine images don't have telnet. It's hard to find. it's in:&lt;br /&gt;
 /app # apk add busybox-extras&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Remember when in a docker, that you (should) always be able to install&lt;br /&gt;
whatever troubleshooting items you need, to replicate a normal bare metal&lt;br /&gt;
install, and then ts from there. e.g. telnet, tcpdump, etc...&lt;br /&gt;
&lt;br /&gt;
e.g.: i tried to connect to an smtp email server (465,587) from VPS but was blocked.&lt;br /&gt;
Either the VPS was blocking outgoing, or the email servers were blocking incoming.&lt;br /&gt;
Since i tried three email servers which were blocked, it looked like the VPS. But I didn't&lt;br /&gt;
want to be a nuisance customer, so I did a reasonable amount of research before contacting&lt;br /&gt;
support.&lt;br /&gt;
&lt;br /&gt;
It turned out the VPS provider was blocking packets. It was a bit of a phantom block&lt;br /&gt;
as they would go outbound from each VPS but then just vanish. Even within a private network where they weren't headed for the WAN, but from VPS to VPS. Ugh. Two hours. Now I know...&lt;br /&gt;
&lt;br /&gt;
==Troubleshooting==&lt;br /&gt;
===Cannot start container: [0] Id already in use #20570===&lt;br /&gt;
* https://github.com/moby/moby/issues/20570&lt;br /&gt;
After update, unable to start container. Solution was found to be:&lt;br /&gt;
 docker-compose down -v then docker-compose up -d&lt;br /&gt;
Container was viewable with&lt;br /&gt;
 docker ps -a (not just docker ps)&lt;br /&gt;
==Poor Design==&lt;br /&gt;
===Creating a docker-compose with a stable or latest tag===&lt;br /&gt;
If you make a docker-compose file, you should link it to a marked version. You can later edit it, to use stable or latest, but one of the strengths of Docker is version control. If you create a docker-compose, always test on a specific version, should you need to roll back in the future. Otherwise, your scripts will fail in 2-20-200 years when the conf files are not supported anymore.&lt;br /&gt;
&lt;br /&gt;
e.g. https://github.com/nucreativa/frontaccounting-docker   (6th commit)&lt;br /&gt;
Here, the nginx config is no longer supported in vhosts, it must be in server_blocks. This would've been avoided by denoting a fixed nginx release instead of tag:latest.&lt;br /&gt;
&lt;br /&gt;
==See Also==&lt;br /&gt;
&lt;br /&gt;
* [[samba_docker_by_dlandon]]&lt;br /&gt;
* [[zencart_docker_compose]]&lt;br /&gt;
&lt;br /&gt;
==External Links==&lt;br /&gt;
* https://github.com/LeCoupa/awesome-cheatsheets/blob/master/tools/docker.sh Information dense cheatsheet (unfortunately github)&lt;br /&gt;
* https://gist.github.com/spalladino/6d981f7b33f6e0afe6bb A million idiots type &amp;quot;thanks&amp;quot;. Also the source for the mysql backup command.&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
{{GNU\Linux}}&lt;/div&gt;</summary>
		<author><name>Adminguy</name></author>
	</entry>
	<entry>
		<id>http://steakwiki.com/index.php?title=Docker&amp;diff=1009</id>
		<title>Docker</title>
		<link rel="alternate" type="text/html" href="http://steakwiki.com/index.php?title=Docker&amp;diff=1009"/>
		<updated>2021-09-11T14:03:05Z</updated>

		<summary type="html">&lt;p&gt;Adminguy: /* ARM is SOL */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;small&amp;gt;Docker is a type of virtualization for Gnu\Linux that allows programs to run and share similar resources, without having a full OS for each image, but while still isolating each 'vm'.&lt;br /&gt;
&lt;br /&gt;
==General Tips==&lt;br /&gt;
It helps to read a book, and then keep it as a Reference. Here Using Docker By Adrian Mouat is a decent book. In fact, you should be reading books on any subject that interests you. Physical paper books, too.&lt;br /&gt;
&lt;br /&gt;
Docker is x86_64. ARM has a separate build. There is no i386.&lt;br /&gt;
&lt;br /&gt;
You will want 'some' RAM. I had 1GB on a P4 machine, and that was not enough. 4GB was enough. &lt;br /&gt;
&lt;br /&gt;
You should always use docker compose. Docker is possible to run on the command line, but with a compose file, you can write everything down in a much simpler fashion. Use compose. It's a separate install, currently. Install it. ''Seriously, just ignore the docker command lines. I consider them useless. More of a red herring for rookies.''&lt;br /&gt;
&lt;br /&gt;
===ARM is SOL===&lt;br /&gt;
I tried to use Docker on ARM, and while you might be able to install docker, you will find that images for your applications may not be there. e.g. you will find Nginx, but you won't find Gitlab. This means that docker is pretty much x86-64 only. (exception: if you make custom Dockerfiles).&lt;br /&gt;
&lt;br /&gt;
==Docker Commands==&lt;br /&gt;
Here are commands you need to know. Just the necessary ones.&lt;br /&gt;
{{cmd| docker-compose up -d}} &lt;br /&gt;
 &lt;br /&gt;
Starts the containers in the docker compose file, if they aren't already started. the -d detaches from the stdout logging. You don't need to use stdout logging, you can use docker logs, but its there if you want it.&lt;br /&gt;
 {{cmd| docker ps }}&lt;br /&gt;
Lists containers running. If one fails to start, you'll see it missing from here&lt;br /&gt;
 {{cmd|docker logs &amp;lt;containername&amp;gt; }}&lt;br /&gt;
Gives you some logging output from the container. Often enough to troubleshoot. (also see tips below).&lt;br /&gt;
 {{cmd|docker exec -it &amp;lt;containername&amp;gt; /bin/bash}}&lt;br /&gt;
This will get you in a shell in the docker container. From here you can do what you need to. Most are debian, and need apt-get install less nano or whatever program you are missing. Ping is missing from possibly all containers, so if you want to test via ping, you'll have to apt-get it.&lt;br /&gt;
 {{cmd|docker-compose restart }}&lt;br /&gt;
This will restart all containers. However, I don't recommend it. Initting containers can get corrupted this way, and also its much easier to restart a single faulty container via...&lt;br /&gt;
 {{cmd|docker restart &amp;lt;containername&amp;gt; }}&lt;br /&gt;
This will restart one single container.&lt;br /&gt;
 {{cmd|docker cp &amp;lt;containername&amp;gt;:/dir/to/file dest }}&lt;br /&gt;
You can copy files from local machine to docker, or vice versa with this. Extremely useful.&lt;br /&gt;
&lt;br /&gt;
===Deleting Containers===&lt;br /&gt;
Less often, you might want to know &lt;br /&gt;
{{cmd|&lt;br /&gt;
 #!/bin/bash&lt;br /&gt;
 docker rm $(docker ps -a -q)&lt;br /&gt;
 docker rmi $(docker images -q) --force}}&lt;br /&gt;
&lt;br /&gt;
This starts over from scratch. This is how easy it is to reboot a docker from square one.  note: below command (rmi), only needed if you want to remove base images. Needed when updating a stable. Not needed when changing other parameters not related to base image. Also, this deletes all containers, which maybe you don't want to do, if you either A) only want to delete certain images you are testing B) have some containers with custom changes saved, and not backed up elsewhere.&lt;br /&gt;
&lt;br /&gt;
===Updating===&lt;br /&gt;
 docker images&lt;br /&gt;
 (shows out of date image)&lt;br /&gt;
 docker pull mysql&lt;br /&gt;
 (downloads new image)&lt;br /&gt;
 docker images&lt;br /&gt;
 (shows two versions of mysql. old and new)&lt;br /&gt;
 docker stop some_container_name&lt;br /&gt;
 docker rmi -f cjklfs23404&lt;br /&gt;
 (where cjklfs23404 is the old container alias under docker images)&lt;br /&gt;
 docker-compose up -d mysql&lt;br /&gt;
&lt;br /&gt;
====Containers don't all Restart?!====&lt;br /&gt;
Make sure to have in your docker compose for each container a '''restart:always'''&lt;br /&gt;
Otherwise, a container won't necessarily start when docker is restarted.&lt;br /&gt;
&lt;br /&gt;
===Search for images===&lt;br /&gt;
 docker search &amp;lt;imagename&amp;gt;&lt;br /&gt;
====Search for Versions of an image====&lt;br /&gt;
What if you want to see what versions are available for a given image? Say you want php, but don't know which to get. hub.docker.com is broken. Requires js, slow, and bad. You can't get a list of images on it easily. &lt;br /&gt;
&lt;br /&gt;
Solution:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
#https://stackoverflow.com/questions/28320134/how-can-i-list-all-tags-for-a-docker-image-on-a-remote-registry&lt;br /&gt;
#$1 means&lt;br /&gt;
#first parameter you pass to this script will be searched&lt;br /&gt;
#e.g. working: debian&lt;br /&gt;
#note: some have multiple layers&lt;br /&gt;
#e.g. gitea/gitea is literally entered as $1 == gitea/gitea  (teste, working)&lt;br /&gt;
# while debian is just debian. so be aware.&lt;br /&gt;
&lt;br /&gt;
wget -q https://registry.hub.docker.com/v1/repositories/$1/tags -O -  \&lt;br /&gt;
| sed -e 's/[][]//g' -e 's/&amp;quot;//g' -e 's/ //g' | tr '}' '\n'  | awk -F: '{print $3}'&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Ref: https://stackoverflow.com/questions/54418542/dockerhub-listing-all-available-versions-of-a-given-image&lt;br /&gt;
&lt;br /&gt;
https://stackoverflow.com/questions/28320134/how-can-i-list-all-tags-for-a-docker-image-on-a-remote-registry&lt;br /&gt;
&lt;br /&gt;
===Save Changes to Docker Image===&lt;br /&gt;
 docker commit&lt;br /&gt;
See official documentation.&lt;br /&gt;
&lt;br /&gt;
===Set IP Address on docker-compose===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 mariadb:&lt;br /&gt;
    image: mariadb:10&lt;br /&gt;
    container_name: mariadb&lt;br /&gt;
    command:&lt;br /&gt;
       - mysqld&lt;br /&gt;
       - --character-set-server=utf8&lt;br /&gt;
       - --collation-server=utf8_bin&lt;br /&gt;
    environment:&lt;br /&gt;
      - MYSQL_ROOT_PASSWORD=admin&lt;br /&gt;
      - MARIADB_DATABASE=guy&lt;br /&gt;
      - MARIADB_USER=user&lt;br /&gt;
      - MARIADB_PASSWORD=passwd&lt;br /&gt;
    volumes:&lt;br /&gt;
      - ./mariadb/appdata:/var/lib/mysql&lt;br /&gt;
      - ./mariadb/config:/etc/mysql&lt;br /&gt;
    networks:&lt;br /&gt;
      somenamefornetwork:&lt;br /&gt;
        ipv4_address: 192.168.12.11&lt;br /&gt;
    ports:&lt;br /&gt;
      - &amp;quot;10055:3306&amp;quot;&lt;br /&gt;
&lt;br /&gt;
networks:&lt;br /&gt;
  somenamefornetwork:&lt;br /&gt;
    ipam:&lt;br /&gt;
      driver: default&lt;br /&gt;
      config:&lt;br /&gt;
        - subnet: &amp;quot;192.168.12.0/24&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Add the networks section to each container.&lt;br /&gt;
&lt;br /&gt;
===Store /var/lib/docker somewhere else===&lt;br /&gt;
i.e. instead of /var/lib/docker put them on external storage...&lt;br /&gt;
Ubuntu/Debian: edit your /etc/default/docker file with the -g option: &lt;br /&gt;
 DOCKER_OPTS=&amp;quot;-dns 8.8.8.8 -dns 8.8.4.4 -g /mnt&amp;quot;&lt;br /&gt;
ref: https://forums.docker.com/t/how-do-i-change-the-docker-image-installation-directory/1169&lt;br /&gt;
&lt;br /&gt;
then &lt;br /&gt;
 stop docker compose&lt;br /&gt;
 stop docker service&lt;br /&gt;
 start docker service&lt;br /&gt;
 start docker compose&lt;br /&gt;
&lt;br /&gt;
the above guide also mentions using a symlink. (that's) A different approach. either should work. This is useful e.g. if you are on a VPS/SBC with limited storage (but have external storage).&lt;br /&gt;
&lt;br /&gt;
==Dockerfile==&lt;br /&gt;
Dockerfiles and compose are slightly confusing. Sometimes you see images run an entrypoint script, sometimes not. In any case, Dockerfiles are fundamental to reproducible builds.&lt;br /&gt;
&lt;br /&gt;
Basic usage is:&lt;br /&gt;
* Docker-compose builds container from dockerfile (say you start with alpine, and install some programs)&lt;br /&gt;
* that container you built is used from thence on. &lt;br /&gt;
* if you want to change dockerfile, make changes and you must call docker-compose up --build otherwise, it will use the old container&lt;br /&gt;
&lt;br /&gt;
For a basic apache server, you might call the following in a cmd at the end of the dockerfile:&lt;br /&gt;
 CMD [&amp;quot;/usr/sbin/apache2&amp;quot;, &amp;quot;-D&amp;quot;, &amp;quot;FOREGROUND&amp;quot;]&lt;br /&gt;
When in doubt, work off of existing examples.&lt;br /&gt;
&lt;br /&gt;
==Volumes==&lt;br /&gt;
Volumes can be handled at least two ways. The simplest is to store files in a local directory which is then mapped to the remote drive.&lt;br /&gt;
&lt;br /&gt;
e.g. docker-compose:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  nginx:&lt;br /&gt;
    image: nginx:####&lt;br /&gt;
    container_name: mynginxserver&lt;br /&gt;
    volumes:&lt;br /&gt;
      - ./nginx.conf:/etc/nginx/nginx.conf&lt;br /&gt;
      - /etc/letsencrypt/:/etc/letsencrypt/&lt;br /&gt;
      - ./local_dir/:/var/www/html/&lt;br /&gt;
      - ./local_logs/:/var/log/nginx/&lt;br /&gt;
    ports:&lt;br /&gt;
      - 80:80&lt;br /&gt;
      - 443:443&lt;br /&gt;
    restart: always&lt;br /&gt;
    logging:&lt;br /&gt;
      driver: &amp;quot;json-file&amp;quot;&lt;br /&gt;
      options:&lt;br /&gt;
        max-size: &amp;quot;200k&amp;quot;&lt;br /&gt;
        max-file: &amp;quot;10&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Here, in the local dir where docker-compose is run, the ./local_dir/ or ./local_logs will store the containers html or logs respectively. Simple. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
However, if you just have a volume, without a local directory, then it will save in /var/ somewhere (unintuitive... bad).&lt;br /&gt;
e.g. from Dolibarr:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
The Dolibarr installation and all data beyond what lives in the database&lt;br /&gt;
 (file uploads, etc) are stored in the unnamed docker volume volume&lt;br /&gt;
/var/www/html and /var/www/documents. The docker daemon will store&lt;br /&gt;
 that data within the docker directory /var/lib/docker/volumes/....&lt;br /&gt;
That means your data is saved even if the container crashes, is stopped&lt;br /&gt;
or deleted.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Specific Tips==&lt;br /&gt;
===YAML is space sensitive===&lt;br /&gt;
When you edit the .yml file for docker-compose, you have to hit spaces in a certain pattern (tabs not allowed). This is absurd, but just be aware. The errors are cryptic, and its often just because the spacing doesn't stick to what it expects.&lt;br /&gt;
===If you restart a containers namesake process, it will probably restart / reset the container===&lt;br /&gt;
So if you are troubleshooting an apache container, you edit some files, then /etc/init.d/apache2 restart, uh oh... You just undid all the edits you made, if they aren't in a permanent volume. You can shell in, make edits, and then exit the shell, but a service restart often resets the container.&lt;br /&gt;
===Consider a single reverse proxy, to handle multiple websites===&lt;br /&gt;
There are many ways to do this. I use an nginx proxy from scratch. You can also use some containers that are built for this purpose (I personally think it's bloated but a lot of people use Jason Wilder's proxy)&lt;br /&gt;
https://web.archive.org/web/https://github.com/jwilder/nginx-proxy - A lot of people swear by this, but I think it's straying too far to the high level.&lt;br /&gt;
===If you use a single reverse proxy, Lets Encrypt can be done easy===&lt;br /&gt;
In this case scenario you would have certbot on the host and a local volume that the proxy has access to which is the webroot of the Lets Encrypt scripts. The nginx proxy entry look something like this:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
location ^~ /.well-known {&lt;br /&gt;
     alias /var/www/html/.well-known/;&lt;br /&gt;
      autoindex on;&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
And this is put in every server declaration of nginx.conf. Real simple, real easy. The docker compose of the nginx proxy is something like:&lt;br /&gt;
&lt;br /&gt;
{{cat|docker-compose.yml|&lt;br /&gt;
nginx:&lt;br /&gt;
    image: nginx:latest&lt;br /&gt;
    container_name: custom_name_for_my_proxy&lt;br /&gt;
    volumes:&lt;br /&gt;
      - ./nginx.conf:/etc/nginx/nginx.conf&lt;br /&gt;
      - /etc/letsencrypt/:/etc/letsencrypt/&lt;br /&gt;
      - ./webroot/:/var/www/html/&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
The volumes section is extremely simple, don't be scared. There are two entries. Local and remote. You specify what folder will be the local directory which will be cloned to the host at the remote path you specify. So, the host runs certbot at /etc/letsencrypt, and this folder is cloned to the nginx proxy container, at the same location. Finally, webroot must be set in certbot, but it prompts you for this. And if you forget or get it wrong, it can be configured somewhere in /etc/letsencrypt. it's a one liner text entry).&lt;br /&gt;
&lt;br /&gt;
===Give every Container a Containername===&lt;br /&gt;
This makes it easier to refer to them later. All you need to do in the compose file is include container\_name: something. Much better than the gibberish they give these names if you don't include it.&lt;br /&gt;
===Beware of Interrupting Initting Containers===&lt;br /&gt;
When you first build a container, it might take 30-60 or more seconds to do whatever it needs to do. If, before then, you restart it... It may get corrupted. This has happened to me more than once. When you are testing a new container, and it doesn't seem to work for some inexplicable reason, create a container with a new name (it will create a new one), or delete the first one, and start it again.&lt;br /&gt;
===Put Apache or Program logs from the Container in a volume that is locally accessible===&lt;br /&gt;
This means you want a volume something like ./containerA\_files/logs:/var/www/log/apache2/ so that you can monitor the logs from your host machine easily. docker logs doesn't have everything.&lt;br /&gt;
===Only Restart Containers you need to Restart===&lt;br /&gt;
You can restart everything with docker-compose restart, but it's faster, and less prone to break initting containers, if you docker restart containername. Do the latter.&lt;br /&gt;
===Volumes Mounting Over Existing Directories===&lt;br /&gt;
As discussed here: https://web.archive.org/web/https://github.com/moby/moby/issues/4361, if you add a volume to an existing container, it will seem to delete the folder's contents. I've seen mixed behaviour with this. Sometimes it deletes it even if you start a new container with the folder... Other times it has not. In any case, just docker cp the files to the folder, then add the volume mount. This may not be the most graceful solution for upgrades, but it will work. Best practices would be here (See: dbxt commented Dec 14, 2014): https://web.archive.org/web/https://github.com/docker-library/wordpress/issues/10&lt;br /&gt;
===If you edit a docker-compose file you must restart the container with Docker-compose===&lt;br /&gt;
If you make a change in docker compose, you must docker stop service, then docker-compose up -d service. Otherwise the changes will not take effect. The mistake here, would be thinking that you could just docker stop service, then docker start service... That doesn't work.&lt;br /&gt;
===Keep verbose logging off your HDD with RAM only logging===&lt;br /&gt;
If you have e.g. apache/nginx write to your HDD with every website visit, it will quickly wear out your HDD (esp. SSD). Put verbose logging in the RAM only with a tmpfs mount. https://docs.docker.com/storage/tmpfs/&lt;br /&gt;
&lt;br /&gt;
e.g. (ref: https://stackoverflow.com/questions/41902930/docker-compose-tmpfs-not-working)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
services:&lt;br /&gt;
  ubuntu:&lt;br /&gt;
    image: ubuntu&lt;br /&gt;
    command: &amp;quot;bash -c 'mount'&amp;quot;&lt;br /&gt;
    volumes:&lt;br /&gt;
      - cache_vol:/var/cache&lt;br /&gt;
      - run_vol:/run&lt;br /&gt;
&lt;br /&gt;
volumes:&lt;br /&gt;
  run_vol:&lt;br /&gt;
    driver_opts:&lt;br /&gt;
      type: tmpfs&lt;br /&gt;
      device: tmpfs&lt;br /&gt;
  cache_vol:&lt;br /&gt;
    driver_opts:&lt;br /&gt;
      type: tmpfs&lt;br /&gt;
      device: tmpfs&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This also allows you to share the tmpfs mounts if needed.&lt;br /&gt;
&lt;br /&gt;
Access it from host via:&lt;br /&gt;
 docker exec -it nginx_server tail -F /run/shm/access.log&lt;br /&gt;
Note that you might think you can do&lt;br /&gt;
 docker container run my_nginx_server tail -F /run/shm/access.log&lt;br /&gt;
But that will only work on container base images, not running containers. To 'execute' a command on a running or existing container, the command you want is exec. (Also used to interactively start bash shell above)&lt;br /&gt;
&lt;br /&gt;
EDIT: Use with discretion. Active data in RAM may use power.&lt;br /&gt;
&lt;br /&gt;
===Mysql Backup / Restore===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# Backup&lt;br /&gt;
docker exec CONTAINER /usr/bin/mysqldump -u root --password=root DATABASE &amp;gt; backup.sql&lt;br /&gt;
&lt;br /&gt;
# Restore&lt;br /&gt;
cat backup.sql | docker exec -i CONTAINER /usr/bin/mysql -u root --password=root DATABASE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
ref: https://gist.github.com/spalladino/6d981f7b33f6e0afe6bb&lt;br /&gt;
May not need to do this, if you keep the DB (ibdata files) in a local directory/volume via docker-compose.yml&lt;br /&gt;
e.g.&lt;br /&gt;
 mydb:&lt;br /&gt;
    image: mysql:9999&lt;br /&gt;
    volumes:&lt;br /&gt;
       - ./db_files:/var/lib/mysql&lt;br /&gt;
    restart: always&lt;br /&gt;
&lt;br /&gt;
===Limit docker logs===&lt;br /&gt;
Docker will keep lots of logs if you don't manage it.&lt;br /&gt;
https://github.com/docker/compose/issues/1083&lt;br /&gt;
https://docs.docker.com/compose/compose-file/#logging&lt;br /&gt;
https://stackoverflow.com/questions/31829587/docker-container-logs-taking-all-my-disk-space&lt;br /&gt;
view (all) logs with &lt;br /&gt;
 docker-compose logs&lt;br /&gt;
To limit a service's logs in docker-compose do the following:&lt;br /&gt;
* find a containers/services entry&lt;br /&gt;
* append to the end (watch the white space &amp;amp; no tabs)&lt;br /&gt;
     logging:&lt;br /&gt;
       driver: &amp;quot;json-file&amp;quot;&lt;br /&gt;
       options:&lt;br /&gt;
         max-size: &amp;quot;200k&amp;quot;&lt;br /&gt;
         max-file: &amp;quot;10&amp;quot;&lt;br /&gt;
The rule with logs, is nothing - unless you need it. Then everything. Any unnecessary logging is taxing the CPU / HDD.&lt;br /&gt;
Which leads me to...&lt;br /&gt;
&lt;br /&gt;
===view details about container===&lt;br /&gt;
To view paths, configuration settings, etc...&lt;br /&gt;
See&lt;br /&gt;
 docker inspect &amp;lt;name or id&amp;gt;&lt;br /&gt;
It's easier to grep these. the search in less wasn't working for me to find .LogPath for example.&lt;br /&gt;
 docker inspect mycontainer | grep log&lt;br /&gt;
Will show where the log files are located.&lt;br /&gt;
&lt;br /&gt;
===Installing Docker-compose from pip or github binary not Debian===&lt;br /&gt;
Subject. See official docker documentation which states the URL of&lt;br /&gt;
github.com/docker/compose/releases or pip.&lt;br /&gt;
&lt;br /&gt;
Pip is probably better.&lt;br /&gt;
 apt-get install python3-pip &lt;br /&gt;
 pip3 install docker-compose&lt;br /&gt;
&lt;br /&gt;
==Troubleshooting==&lt;br /&gt;
===Cannot start container: [0] Id already in use #20570===&lt;br /&gt;
* https://github.com/moby/moby/issues/20570&lt;br /&gt;
After update, unable to start container. Solution was found to be:&lt;br /&gt;
 docker-compose down -v then docker-compose up -d&lt;br /&gt;
Container was viewable with&lt;br /&gt;
 docker ps -a (not just docker ps)&lt;br /&gt;
==Poor Design==&lt;br /&gt;
===Creating a docker-compose with a stable or latest tag===&lt;br /&gt;
If you make a docker-compose file, you should link it to a marked version. You can later edit it, to use stable or latest, but one of the strengths of Docker is version control. If you create a docker-compose, always test on a specific version, should you need to roll back in the future. Otherwise, your scripts will fail in 2-20-200 years when the conf files are not supported anymore.&lt;br /&gt;
&lt;br /&gt;
e.g. https://github.com/nucreativa/frontaccounting-docker   (6th commit)&lt;br /&gt;
Here, the nginx config is no longer supported in vhosts, it must be in server_blocks. This would've been avoided by denoting a fixed nginx release instead of tag:latest.&lt;br /&gt;
&lt;br /&gt;
==See Also==&lt;br /&gt;
&lt;br /&gt;
* [[samba_docker_by_dlandon]]&lt;br /&gt;
* [[zencart_docker_compose]]&lt;br /&gt;
&lt;br /&gt;
==External Links==&lt;br /&gt;
* https://github.com/LeCoupa/awesome-cheatsheets/blob/master/tools/docker.sh Information dense cheatsheet (unfortunately github)&lt;br /&gt;
* https://gist.github.com/spalladino/6d981f7b33f6e0afe6bb A million idiots type &amp;quot;thanks&amp;quot;. Also the source for the mysql backup command.&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
{{GNU\Linux}}&lt;/div&gt;</summary>
		<author><name>Adminguy</name></author>
	</entry>
	<entry>
		<id>http://steakwiki.com/index.php?title=Docker&amp;diff=1008</id>
		<title>Docker</title>
		<link rel="alternate" type="text/html" href="http://steakwiki.com/index.php?title=Docker&amp;diff=1008"/>
		<updated>2021-09-11T14:02:16Z</updated>

		<summary type="html">&lt;p&gt;Adminguy: /* Store /var/lib/docker somewhere else */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;small&amp;gt;Docker is a type of virtualization for Gnu\Linux that allows programs to run and share similar resources, without having a full OS for each image, but while still isolating each 'vm'.&lt;br /&gt;
&lt;br /&gt;
==General Tips==&lt;br /&gt;
It helps to read a book, and then keep it as a Reference. Here Using Docker By Adrian Mouat is a decent book. In fact, you should be reading books on any subject that interests you. Physical paper books, too.&lt;br /&gt;
&lt;br /&gt;
Docker is x86_64. ARM has a separate build. There is no i386.&lt;br /&gt;
&lt;br /&gt;
You will want 'some' RAM. I had 1GB on a P4 machine, and that was not enough. 4GB was enough. &lt;br /&gt;
&lt;br /&gt;
You should always use docker compose. Docker is possible to run on the command line, but with a compose file, you can write everything down in a much simpler fashion. Use compose. It's a separate install, currently. Install it. ''Seriously, just ignore the docker command lines. I consider them useless. More of a red herring for rookies.''&lt;br /&gt;
&lt;br /&gt;
===ARM is SOL===&lt;br /&gt;
I tried to use Docker on ARM, and while you might be able to install docker, you will find that images for your applications may not be there. e.g. you will find Nginx, but you won't find Gitlab. This means that docker is pretty much x86-64 only.&lt;br /&gt;
&lt;br /&gt;
==Docker Commands==&lt;br /&gt;
Here are commands you need to know. Just the necessary ones.&lt;br /&gt;
{{cmd| docker-compose up -d}} &lt;br /&gt;
 &lt;br /&gt;
Starts the containers in the docker compose file, if they aren't already started. the -d detaches from the stdout logging. You don't need to use stdout logging, you can use docker logs, but its there if you want it.&lt;br /&gt;
 {{cmd| docker ps }}&lt;br /&gt;
Lists containers running. If one fails to start, you'll see it missing from here&lt;br /&gt;
 {{cmd|docker logs &amp;lt;containername&amp;gt; }}&lt;br /&gt;
Gives you some logging output from the container. Often enough to troubleshoot. (also see tips below).&lt;br /&gt;
 {{cmd|docker exec -it &amp;lt;containername&amp;gt; /bin/bash}}&lt;br /&gt;
This will get you in a shell in the docker container. From here you can do what you need to. Most are debian, and need apt-get install less nano or whatever program you are missing. Ping is missing from possibly all containers, so if you want to test via ping, you'll have to apt-get it.&lt;br /&gt;
 {{cmd|docker-compose restart }}&lt;br /&gt;
This will restart all containers. However, I don't recommend it. Initting containers can get corrupted this way, and also its much easier to restart a single faulty container via...&lt;br /&gt;
 {{cmd|docker restart &amp;lt;containername&amp;gt; }}&lt;br /&gt;
This will restart one single container.&lt;br /&gt;
 {{cmd|docker cp &amp;lt;containername&amp;gt;:/dir/to/file dest }}&lt;br /&gt;
You can copy files from local machine to docker, or vice versa with this. Extremely useful.&lt;br /&gt;
&lt;br /&gt;
===Deleting Containers===&lt;br /&gt;
Less often, you might want to know &lt;br /&gt;
{{cmd|&lt;br /&gt;
 #!/bin/bash&lt;br /&gt;
 docker rm $(docker ps -a -q)&lt;br /&gt;
 docker rmi $(docker images -q) --force}}&lt;br /&gt;
&lt;br /&gt;
This starts over from scratch. This is how easy it is to reboot a docker from square one.  note: below command (rmi), only needed if you want to remove base images. Needed when updating a stable. Not needed when changing other parameters not related to base image. Also, this deletes all containers, which maybe you don't want to do, if you either A) only want to delete certain images you are testing B) have some containers with custom changes saved, and not backed up elsewhere.&lt;br /&gt;
&lt;br /&gt;
===Updating===&lt;br /&gt;
 docker images&lt;br /&gt;
 (shows out of date image)&lt;br /&gt;
 docker pull mysql&lt;br /&gt;
 (downloads new image)&lt;br /&gt;
 docker images&lt;br /&gt;
 (shows two versions of mysql. old and new)&lt;br /&gt;
 docker stop some_container_name&lt;br /&gt;
 docker rmi -f cjklfs23404&lt;br /&gt;
 (where cjklfs23404 is the old container alias under docker images)&lt;br /&gt;
 docker-compose up -d mysql&lt;br /&gt;
&lt;br /&gt;
====Containers don't all Restart?!====&lt;br /&gt;
Make sure to have in your docker compose for each container a '''restart:always'''&lt;br /&gt;
Otherwise, a container won't necessarily start when docker is restarted.&lt;br /&gt;
&lt;br /&gt;
===Search for images===&lt;br /&gt;
 docker search &amp;lt;imagename&amp;gt;&lt;br /&gt;
====Search for Versions of an image====&lt;br /&gt;
What if you want to see what versions are available for a given image? Say you want php, but don't know which to get. hub.docker.com is broken. Requires js, slow, and bad. You can't get a list of images on it easily. &lt;br /&gt;
&lt;br /&gt;
Solution:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
#https://stackoverflow.com/questions/28320134/how-can-i-list-all-tags-for-a-docker-image-on-a-remote-registry&lt;br /&gt;
#$1 means&lt;br /&gt;
#first parameter you pass to this script will be searched&lt;br /&gt;
#e.g. working: debian&lt;br /&gt;
#note: some have multiple layers&lt;br /&gt;
#e.g. gitea/gitea is literally entered as $1 == gitea/gitea  (teste, working)&lt;br /&gt;
# while debian is just debian. so be aware.&lt;br /&gt;
&lt;br /&gt;
wget -q https://registry.hub.docker.com/v1/repositories/$1/tags -O -  \&lt;br /&gt;
| sed -e 's/[][]//g' -e 's/&amp;quot;//g' -e 's/ //g' | tr '}' '\n'  | awk -F: '{print $3}'&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Ref: https://stackoverflow.com/questions/54418542/dockerhub-listing-all-available-versions-of-a-given-image&lt;br /&gt;
&lt;br /&gt;
https://stackoverflow.com/questions/28320134/how-can-i-list-all-tags-for-a-docker-image-on-a-remote-registry&lt;br /&gt;
&lt;br /&gt;
===Save Changes to Docker Image===&lt;br /&gt;
 docker commit&lt;br /&gt;
See official documentation.&lt;br /&gt;
&lt;br /&gt;
===Set IP Address on docker-compose===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 mariadb:&lt;br /&gt;
    image: mariadb:10&lt;br /&gt;
    container_name: mariadb&lt;br /&gt;
    command:&lt;br /&gt;
       - mysqld&lt;br /&gt;
       - --character-set-server=utf8&lt;br /&gt;
       - --collation-server=utf8_bin&lt;br /&gt;
    environment:&lt;br /&gt;
      - MYSQL_ROOT_PASSWORD=admin&lt;br /&gt;
      - MARIADB_DATABASE=guy&lt;br /&gt;
      - MARIADB_USER=user&lt;br /&gt;
      - MARIADB_PASSWORD=passwd&lt;br /&gt;
    volumes:&lt;br /&gt;
      - ./mariadb/appdata:/var/lib/mysql&lt;br /&gt;
      - ./mariadb/config:/etc/mysql&lt;br /&gt;
    networks:&lt;br /&gt;
      somenamefornetwork:&lt;br /&gt;
        ipv4_address: 192.168.12.11&lt;br /&gt;
    ports:&lt;br /&gt;
      - &amp;quot;10055:3306&amp;quot;&lt;br /&gt;
&lt;br /&gt;
networks:&lt;br /&gt;
  somenamefornetwork:&lt;br /&gt;
    ipam:&lt;br /&gt;
      driver: default&lt;br /&gt;
      config:&lt;br /&gt;
        - subnet: &amp;quot;192.168.12.0/24&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Add the networks section to each container.&lt;br /&gt;
&lt;br /&gt;
===Store /var/lib/docker somewhere else===&lt;br /&gt;
i.e. instead of /var/lib/docker put them on external storage...&lt;br /&gt;
Ubuntu/Debian: edit your /etc/default/docker file with the -g option: &lt;br /&gt;
 DOCKER_OPTS=&amp;quot;-dns 8.8.8.8 -dns 8.8.4.4 -g /mnt&amp;quot;&lt;br /&gt;
ref: https://forums.docker.com/t/how-do-i-change-the-docker-image-installation-directory/1169&lt;br /&gt;
&lt;br /&gt;
then &lt;br /&gt;
 stop docker compose&lt;br /&gt;
 stop docker service&lt;br /&gt;
 start docker service&lt;br /&gt;
 start docker compose&lt;br /&gt;
&lt;br /&gt;
the above guide also mentions using a symlink. (that's) A different approach. either should work. This is useful e.g. if you are on a VPS/SBC with limited storage (but have external storage).&lt;br /&gt;
&lt;br /&gt;
==Dockerfile==&lt;br /&gt;
Dockerfiles and compose are slightly confusing. Sometimes you see images run an entrypoint script, sometimes not. In any case, Dockerfiles are fundamental to reproducible builds.&lt;br /&gt;
&lt;br /&gt;
Basic usage is:&lt;br /&gt;
* Docker-compose builds container from dockerfile (say you start with alpine, and install some programs)&lt;br /&gt;
* that container you built is used from thence on. &lt;br /&gt;
* if you want to change dockerfile, make changes and you must call docker-compose up --build otherwise, it will use the old container&lt;br /&gt;
&lt;br /&gt;
For a basic apache server, you might call the following in a cmd at the end of the dockerfile:&lt;br /&gt;
 CMD [&amp;quot;/usr/sbin/apache2&amp;quot;, &amp;quot;-D&amp;quot;, &amp;quot;FOREGROUND&amp;quot;]&lt;br /&gt;
When in doubt, work off of existing examples.&lt;br /&gt;
&lt;br /&gt;
==Volumes==&lt;br /&gt;
Volumes can be handled at least two ways. The simplest is to store files in a local directory which is then mapped to the remote drive.&lt;br /&gt;
&lt;br /&gt;
e.g. docker-compose:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  nginx:&lt;br /&gt;
    image: nginx:####&lt;br /&gt;
    container_name: mynginxserver&lt;br /&gt;
    volumes:&lt;br /&gt;
      - ./nginx.conf:/etc/nginx/nginx.conf&lt;br /&gt;
      - /etc/letsencrypt/:/etc/letsencrypt/&lt;br /&gt;
      - ./local_dir/:/var/www/html/&lt;br /&gt;
      - ./local_logs/:/var/log/nginx/&lt;br /&gt;
    ports:&lt;br /&gt;
      - 80:80&lt;br /&gt;
      - 443:443&lt;br /&gt;
    restart: always&lt;br /&gt;
    logging:&lt;br /&gt;
      driver: &amp;quot;json-file&amp;quot;&lt;br /&gt;
      options:&lt;br /&gt;
        max-size: &amp;quot;200k&amp;quot;&lt;br /&gt;
        max-file: &amp;quot;10&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Here, in the local dir where docker-compose is run, the ./local_dir/ or ./local_logs will store the containers html or logs respectively. Simple. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
However, if you just have a volume, without a local directory, then it will save in /var/ somewhere (unintuitive... bad).&lt;br /&gt;
e.g. from Dolibarr:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
The Dolibarr installation and all data beyond what lives in the database&lt;br /&gt;
 (file uploads, etc) are stored in the unnamed docker volume volume&lt;br /&gt;
/var/www/html and /var/www/documents. The docker daemon will store&lt;br /&gt;
 that data within the docker directory /var/lib/docker/volumes/....&lt;br /&gt;
That means your data is saved even if the container crashes, is stopped&lt;br /&gt;
or deleted.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Specific Tips==&lt;br /&gt;
===YAML is space sensitive===&lt;br /&gt;
When you edit the .yml file for docker-compose, you have to hit spaces in a certain pattern (tabs not allowed). This is absurd, but just be aware. The errors are cryptic, and its often just because the spacing doesn't stick to what it expects.&lt;br /&gt;
===If you restart a containers namesake process, it will probably restart / reset the container===&lt;br /&gt;
So if you are troubleshooting an apache container, you edit some files, then /etc/init.d/apache2 restart, uh oh... You just undid all the edits you made, if they aren't in a permanent volume. You can shell in, make edits, and then exit the shell, but a service restart often resets the container.&lt;br /&gt;
===Consider a single reverse proxy, to handle multiple websites===&lt;br /&gt;
There are many ways to do this. I use an nginx proxy from scratch. You can also use some containers that are built for this purpose (I personally think it's bloated but a lot of people use Jason Wilder's proxy)&lt;br /&gt;
https://web.archive.org/web/https://github.com/jwilder/nginx-proxy - A lot of people swear by this, but I think it's straying too far to the high level.&lt;br /&gt;
===If you use a single reverse proxy, Lets Encrypt can be done easy===&lt;br /&gt;
In this case scenario you would have certbot on the host and a local volume that the proxy has access to which is the webroot of the Lets Encrypt scripts. The nginx proxy entry look something like this:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
location ^~ /.well-known {&lt;br /&gt;
     alias /var/www/html/.well-known/;&lt;br /&gt;
      autoindex on;&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
And this is put in every server declaration of nginx.conf. Real simple, real easy. The docker compose of the nginx proxy is something like:&lt;br /&gt;
&lt;br /&gt;
{{cat|docker-compose.yml|&lt;br /&gt;
nginx:&lt;br /&gt;
    image: nginx:latest&lt;br /&gt;
    container_name: custom_name_for_my_proxy&lt;br /&gt;
    volumes:&lt;br /&gt;
      - ./nginx.conf:/etc/nginx/nginx.conf&lt;br /&gt;
      - /etc/letsencrypt/:/etc/letsencrypt/&lt;br /&gt;
      - ./webroot/:/var/www/html/&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
The volumes section is extremely simple, don't be scared. There are two entries. Local and remote. You specify what folder will be the local directory which will be cloned to the host at the remote path you specify. So, the host runs certbot at /etc/letsencrypt, and this folder is cloned to the nginx proxy container, at the same location. Finally, webroot must be set in certbot, but it prompts you for this. And if you forget or get it wrong, it can be configured somewhere in /etc/letsencrypt. it's a one liner text entry).&lt;br /&gt;
&lt;br /&gt;
===Give every Container a Containername===&lt;br /&gt;
This makes it easier to refer to them later. All you need to do in the compose file is include container\_name: something. Much better than the gibberish they give these names if you don't include it.&lt;br /&gt;
===Beware of Interrupting Initting Containers===&lt;br /&gt;
When you first build a container, it might take 30-60 or more seconds to do whatever it needs to do. If, before then, you restart it... It may get corrupted. This has happened to me more than once. When you are testing a new container, and it doesn't seem to work for some inexplicable reason, create a container with a new name (it will create a new one), or delete the first one, and start it again.&lt;br /&gt;
===Put Apache or Program logs from the Container in a volume that is locally accessible===&lt;br /&gt;
This means you want a volume something like ./containerA\_files/logs:/var/www/log/apache2/ so that you can monitor the logs from your host machine easily. docker logs doesn't have everything.&lt;br /&gt;
===Only Restart Containers you need to Restart===&lt;br /&gt;
You can restart everything with docker-compose restart, but it's faster, and less prone to break initting containers, if you docker restart containername. Do the latter.&lt;br /&gt;
===Volumes Mounting Over Existing Directories===&lt;br /&gt;
As discussed here: https://web.archive.org/web/https://github.com/moby/moby/issues/4361, if you add a volume to an existing container, it will seem to delete the folder's contents. I've seen mixed behaviour with this. Sometimes it deletes it even if you start a new container with the folder... Other times it has not. In any case, just docker cp the files to the folder, then add the volume mount. This may not be the most graceful solution for upgrades, but it will work. Best practices would be here (See: dbxt commented Dec 14, 2014): https://web.archive.org/web/https://github.com/docker-library/wordpress/issues/10&lt;br /&gt;
===If you edit a docker-compose file you must restart the container with Docker-compose===&lt;br /&gt;
If you make a change in docker compose, you must docker stop service, then docker-compose up -d service. Otherwise the changes will not take effect. The mistake here, would be thinking that you could just docker stop service, then docker start service... That doesn't work.&lt;br /&gt;
===Keep verbose logging off your HDD with RAM only logging===&lt;br /&gt;
If you have e.g. apache/nginx write to your HDD with every website visit, it will quickly wear out your HDD (esp. SSD). Put verbose logging in the RAM only with a tmpfs mount. https://docs.docker.com/storage/tmpfs/&lt;br /&gt;
&lt;br /&gt;
e.g. (ref: https://stackoverflow.com/questions/41902930/docker-compose-tmpfs-not-working)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
services:&lt;br /&gt;
  ubuntu:&lt;br /&gt;
    image: ubuntu&lt;br /&gt;
    command: &amp;quot;bash -c 'mount'&amp;quot;&lt;br /&gt;
    volumes:&lt;br /&gt;
      - cache_vol:/var/cache&lt;br /&gt;
      - run_vol:/run&lt;br /&gt;
&lt;br /&gt;
volumes:&lt;br /&gt;
  run_vol:&lt;br /&gt;
    driver_opts:&lt;br /&gt;
      type: tmpfs&lt;br /&gt;
      device: tmpfs&lt;br /&gt;
  cache_vol:&lt;br /&gt;
    driver_opts:&lt;br /&gt;
      type: tmpfs&lt;br /&gt;
      device: tmpfs&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This also allows you to share the tmpfs mounts if needed.&lt;br /&gt;
&lt;br /&gt;
Access it from host via:&lt;br /&gt;
 docker exec -it nginx_server tail -F /run/shm/access.log&lt;br /&gt;
Note that you might think you can do&lt;br /&gt;
 docker container run my_nginx_server tail -F /run/shm/access.log&lt;br /&gt;
But that will only work on container base images, not running containers. To 'execute' a command on a running or existing container, the command you want is exec. (Also used to interactively start bash shell above)&lt;br /&gt;
&lt;br /&gt;
EDIT: Use with discretion. Active data in RAM may use power.&lt;br /&gt;
&lt;br /&gt;
===Mysql Backup / Restore===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# Backup&lt;br /&gt;
docker exec CONTAINER /usr/bin/mysqldump -u root --password=root DATABASE &amp;gt; backup.sql&lt;br /&gt;
&lt;br /&gt;
# Restore&lt;br /&gt;
cat backup.sql | docker exec -i CONTAINER /usr/bin/mysql -u root --password=root DATABASE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
ref: https://gist.github.com/spalladino/6d981f7b33f6e0afe6bb&lt;br /&gt;
May not need to do this, if you keep the DB (ibdata files) in a local directory/volume via docker-compose.yml&lt;br /&gt;
e.g.&lt;br /&gt;
 mydb:&lt;br /&gt;
    image: mysql:9999&lt;br /&gt;
    volumes:&lt;br /&gt;
       - ./db_files:/var/lib/mysql&lt;br /&gt;
    restart: always&lt;br /&gt;
&lt;br /&gt;
===Limit docker logs===&lt;br /&gt;
Docker will keep lots of logs if you don't manage it.&lt;br /&gt;
https://github.com/docker/compose/issues/1083&lt;br /&gt;
https://docs.docker.com/compose/compose-file/#logging&lt;br /&gt;
https://stackoverflow.com/questions/31829587/docker-container-logs-taking-all-my-disk-space&lt;br /&gt;
view (all) logs with &lt;br /&gt;
 docker-compose logs&lt;br /&gt;
To limit a service's logs in docker-compose do the following:&lt;br /&gt;
* find a containers/services entry&lt;br /&gt;
* append to the end (watch the white space &amp;amp; no tabs)&lt;br /&gt;
     logging:&lt;br /&gt;
       driver: &amp;quot;json-file&amp;quot;&lt;br /&gt;
       options:&lt;br /&gt;
         max-size: &amp;quot;200k&amp;quot;&lt;br /&gt;
         max-file: &amp;quot;10&amp;quot;&lt;br /&gt;
The rule with logs, is nothing - unless you need it. Then everything. Any unnecessary logging is taxing the CPU / HDD.&lt;br /&gt;
Which leads me to...&lt;br /&gt;
&lt;br /&gt;
===view details about container===&lt;br /&gt;
To view paths, configuration settings, etc...&lt;br /&gt;
See&lt;br /&gt;
 docker inspect &amp;lt;name or id&amp;gt;&lt;br /&gt;
It's easier to grep these. the search in less wasn't working for me to find .LogPath for example.&lt;br /&gt;
 docker inspect mycontainer | grep log&lt;br /&gt;
Will show where the log files are located.&lt;br /&gt;
&lt;br /&gt;
===Installing Docker-compose from pip or github binary not Debian===&lt;br /&gt;
Subject. See official docker documentation which states the URL of&lt;br /&gt;
github.com/docker/compose/releases or pip.&lt;br /&gt;
&lt;br /&gt;
Pip is probably better.&lt;br /&gt;
 apt-get install python3-pip &lt;br /&gt;
 pip3 install docker-compose&lt;br /&gt;
&lt;br /&gt;
==Troubleshooting==&lt;br /&gt;
===Cannot start container: [0] Id already in use #20570===&lt;br /&gt;
* https://github.com/moby/moby/issues/20570&lt;br /&gt;
After update, unable to start container. Solution was found to be:&lt;br /&gt;
 docker-compose down -v then docker-compose up -d&lt;br /&gt;
Container was viewable with&lt;br /&gt;
 docker ps -a (not just docker ps)&lt;br /&gt;
==Poor Design==&lt;br /&gt;
===Creating a docker-compose with a stable or latest tag===&lt;br /&gt;
If you make a docker-compose file, you should link it to a marked version. You can later edit it, to use stable or latest, but one of the strengths of Docker is version control. If you create a docker-compose, always test on a specific version, should you need to roll back in the future. Otherwise, your scripts will fail in 2-20-200 years when the conf files are not supported anymore.&lt;br /&gt;
&lt;br /&gt;
e.g. https://github.com/nucreativa/frontaccounting-docker   (6th commit)&lt;br /&gt;
Here, the nginx config is no longer supported in vhosts, it must be in server_blocks. This would've been avoided by denoting a fixed nginx release instead of tag:latest.&lt;br /&gt;
&lt;br /&gt;
==See Also==&lt;br /&gt;
&lt;br /&gt;
* [[samba_docker_by_dlandon]]&lt;br /&gt;
* [[zencart_docker_compose]]&lt;br /&gt;
&lt;br /&gt;
==External Links==&lt;br /&gt;
* https://github.com/LeCoupa/awesome-cheatsheets/blob/master/tools/docker.sh Information dense cheatsheet (unfortunately github)&lt;br /&gt;
* https://gist.github.com/spalladino/6d981f7b33f6e0afe6bb A million idiots type &amp;quot;thanks&amp;quot;. Also the source for the mysql backup command.&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
{{GNU\Linux}}&lt;/div&gt;</summary>
		<author><name>Adminguy</name></author>
	</entry>
	<entry>
		<id>http://steakwiki.com/index.php?title=Docker&amp;diff=1007</id>
		<title>Docker</title>
		<link rel="alternate" type="text/html" href="http://steakwiki.com/index.php?title=Docker&amp;diff=1007"/>
		<updated>2021-09-11T14:01:08Z</updated>

		<summary type="html">&lt;p&gt;Adminguy: /* Set IP Address on docker-compose */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;small&amp;gt;Docker is a type of virtualization for Gnu\Linux that allows programs to run and share similar resources, without having a full OS for each image, but while still isolating each 'vm'.&lt;br /&gt;
&lt;br /&gt;
==General Tips==&lt;br /&gt;
It helps to read a book, and then keep it as a Reference. Here Using Docker By Adrian Mouat is a decent book. In fact, you should be reading books on any subject that interests you. Physical paper books, too.&lt;br /&gt;
&lt;br /&gt;
Docker is x86_64. ARM has a separate build. There is no i386.&lt;br /&gt;
&lt;br /&gt;
You will want 'some' RAM. I had 1GB on a P4 machine, and that was not enough. 4GB was enough. &lt;br /&gt;
&lt;br /&gt;
You should always use docker compose. Docker is possible to run on the command line, but with a compose file, you can write everything down in a much simpler fashion. Use compose. It's a separate install, currently. Install it. ''Seriously, just ignore the docker command lines. I consider them useless. More of a red herring for rookies.''&lt;br /&gt;
&lt;br /&gt;
===ARM is SOL===&lt;br /&gt;
I tried to use Docker on ARM, and while you might be able to install docker, you will find that images for your applications may not be there. e.g. you will find Nginx, but you won't find Gitlab. This means that docker is pretty much x86-64 only.&lt;br /&gt;
&lt;br /&gt;
==Docker Commands==&lt;br /&gt;
Here are commands you need to know. Just the necessary ones.&lt;br /&gt;
{{cmd| docker-compose up -d}} &lt;br /&gt;
 &lt;br /&gt;
Starts the containers in the docker compose file, if they aren't already started. the -d detaches from the stdout logging. You don't need to use stdout logging, you can use docker logs, but its there if you want it.&lt;br /&gt;
 {{cmd| docker ps }}&lt;br /&gt;
Lists containers running. If one fails to start, you'll see it missing from here&lt;br /&gt;
 {{cmd|docker logs &amp;lt;containername&amp;gt; }}&lt;br /&gt;
Gives you some logging output from the container. Often enough to troubleshoot. (also see tips below).&lt;br /&gt;
 {{cmd|docker exec -it &amp;lt;containername&amp;gt; /bin/bash}}&lt;br /&gt;
This will get you in a shell in the docker container. From here you can do what you need to. Most are debian, and need apt-get install less nano or whatever program you are missing. Ping is missing from possibly all containers, so if you want to test via ping, you'll have to apt-get it.&lt;br /&gt;
 {{cmd|docker-compose restart }}&lt;br /&gt;
This will restart all containers. However, I don't recommend it. Initting containers can get corrupted this way, and also its much easier to restart a single faulty container via...&lt;br /&gt;
 {{cmd|docker restart &amp;lt;containername&amp;gt; }}&lt;br /&gt;
This will restart one single container.&lt;br /&gt;
 {{cmd|docker cp &amp;lt;containername&amp;gt;:/dir/to/file dest }}&lt;br /&gt;
You can copy files from local machine to docker, or vice versa with this. Extremely useful.&lt;br /&gt;
&lt;br /&gt;
===Deleting Containers===&lt;br /&gt;
Less often, you might want to know &lt;br /&gt;
{{cmd|&lt;br /&gt;
 #!/bin/bash&lt;br /&gt;
 docker rm $(docker ps -a -q)&lt;br /&gt;
 docker rmi $(docker images -q) --force}}&lt;br /&gt;
&lt;br /&gt;
This starts over from scratch. This is how easy it is to reboot a docker from square one.  note: below command (rmi), only needed if you want to remove base images. Needed when updating a stable. Not needed when changing other parameters not related to base image. Also, this deletes all containers, which maybe you don't want to do, if you either A) only want to delete certain images you are testing B) have some containers with custom changes saved, and not backed up elsewhere.&lt;br /&gt;
&lt;br /&gt;
===Updating===&lt;br /&gt;
 docker images&lt;br /&gt;
 (shows out of date image)&lt;br /&gt;
 docker pull mysql&lt;br /&gt;
 (downloads new image)&lt;br /&gt;
 docker images&lt;br /&gt;
 (shows two versions of mysql. old and new)&lt;br /&gt;
 docker stop some_container_name&lt;br /&gt;
 docker rmi -f cjklfs23404&lt;br /&gt;
 (where cjklfs23404 is the old container alias under docker images)&lt;br /&gt;
 docker-compose up -d mysql&lt;br /&gt;
&lt;br /&gt;
====Containers don't all Restart?!====&lt;br /&gt;
Make sure to have in your docker compose for each container a '''restart:always'''&lt;br /&gt;
Otherwise, a container won't necessarily start when docker is restarted.&lt;br /&gt;
&lt;br /&gt;
===Search for images===&lt;br /&gt;
 docker search &amp;lt;imagename&amp;gt;&lt;br /&gt;
====Search for Versions of an image====&lt;br /&gt;
What if you want to see what versions are available for a given image? Say you want php, but don't know which to get. hub.docker.com is broken. Requires js, slow, and bad. You can't get a list of images on it easily. &lt;br /&gt;
&lt;br /&gt;
Solution:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
#https://stackoverflow.com/questions/28320134/how-can-i-list-all-tags-for-a-docker-image-on-a-remote-registry&lt;br /&gt;
#$1 means&lt;br /&gt;
#first parameter you pass to this script will be searched&lt;br /&gt;
#e.g. working: debian&lt;br /&gt;
#note: some have multiple layers&lt;br /&gt;
#e.g. gitea/gitea is literally entered as $1 == gitea/gitea  (teste, working)&lt;br /&gt;
# while debian is just debian. so be aware.&lt;br /&gt;
&lt;br /&gt;
wget -q https://registry.hub.docker.com/v1/repositories/$1/tags -O -  \&lt;br /&gt;
| sed -e 's/[][]//g' -e 's/&amp;quot;//g' -e 's/ //g' | tr '}' '\n'  | awk -F: '{print $3}'&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Ref: https://stackoverflow.com/questions/54418542/dockerhub-listing-all-available-versions-of-a-given-image&lt;br /&gt;
&lt;br /&gt;
https://stackoverflow.com/questions/28320134/how-can-i-list-all-tags-for-a-docker-image-on-a-remote-registry&lt;br /&gt;
&lt;br /&gt;
===Save Changes to Docker Image===&lt;br /&gt;
 docker commit&lt;br /&gt;
See official documentation.&lt;br /&gt;
&lt;br /&gt;
===Set IP Address on docker-compose===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 mariadb:&lt;br /&gt;
    image: mariadb:10&lt;br /&gt;
    container_name: mariadb&lt;br /&gt;
    command:&lt;br /&gt;
       - mysqld&lt;br /&gt;
       - --character-set-server=utf8&lt;br /&gt;
       - --collation-server=utf8_bin&lt;br /&gt;
    environment:&lt;br /&gt;
      - MYSQL_ROOT_PASSWORD=admin&lt;br /&gt;
      - MARIADB_DATABASE=guy&lt;br /&gt;
      - MARIADB_USER=user&lt;br /&gt;
      - MARIADB_PASSWORD=passwd&lt;br /&gt;
    volumes:&lt;br /&gt;
      - ./mariadb/appdata:/var/lib/mysql&lt;br /&gt;
      - ./mariadb/config:/etc/mysql&lt;br /&gt;
    networks:&lt;br /&gt;
      somenamefornetwork:&lt;br /&gt;
        ipv4_address: 192.168.12.11&lt;br /&gt;
    ports:&lt;br /&gt;
      - &amp;quot;10055:3306&amp;quot;&lt;br /&gt;
&lt;br /&gt;
networks:&lt;br /&gt;
  somenamefornetwork:&lt;br /&gt;
    ipam:&lt;br /&gt;
      driver: default&lt;br /&gt;
      config:&lt;br /&gt;
        - subnet: &amp;quot;192.168.12.0/24&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Add the networks section to each container.&lt;br /&gt;
&lt;br /&gt;
===Store /var/lib/docker somewhere else===&lt;br /&gt;
i.e. instead of /var/lib/docker put them on external storage...&lt;br /&gt;
Ubuntu/Debian: edit your /etc/default/docker file with the -g option: &lt;br /&gt;
 DOCKER_OPTS=&amp;quot;-dns 8.8.8.8 -dns 8.8.4.4 -g /mnt&amp;quot;&lt;br /&gt;
ref: https://forums.docker.com/t/how-do-i-change-the-docker-image-installation-directory/1169&lt;br /&gt;
&lt;br /&gt;
then &lt;br /&gt;
 stop docker compose&lt;br /&gt;
 stop docker service&lt;br /&gt;
 start docker service&lt;br /&gt;
 start docker compose&lt;br /&gt;
&lt;br /&gt;
the above guide also mentions using a symlink. (that's) A different approach. either should work.&lt;br /&gt;
&lt;br /&gt;
==Dockerfile==&lt;br /&gt;
Dockerfiles and compose are slightly confusing. Sometimes you see images run an entrypoint script, sometimes not. In any case, Dockerfiles are fundamental to reproducible builds.&lt;br /&gt;
&lt;br /&gt;
Basic usage is:&lt;br /&gt;
* Docker-compose builds container from dockerfile (say you start with alpine, and install some programs)&lt;br /&gt;
* that container you built is used from thence on. &lt;br /&gt;
* if you want to change dockerfile, make changes and you must call docker-compose up --build otherwise, it will use the old container&lt;br /&gt;
&lt;br /&gt;
For a basic apache server, you might call the following in a cmd at the end of the dockerfile:&lt;br /&gt;
 CMD [&amp;quot;/usr/sbin/apache2&amp;quot;, &amp;quot;-D&amp;quot;, &amp;quot;FOREGROUND&amp;quot;]&lt;br /&gt;
When in doubt, work off of existing examples.&lt;br /&gt;
&lt;br /&gt;
==Volumes==&lt;br /&gt;
Volumes can be handled at least two ways. The simplest is to store files in a local directory which is then mapped to the remote drive.&lt;br /&gt;
&lt;br /&gt;
e.g. docker-compose:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  nginx:&lt;br /&gt;
    image: nginx:####&lt;br /&gt;
    container_name: mynginxserver&lt;br /&gt;
    volumes:&lt;br /&gt;
      - ./nginx.conf:/etc/nginx/nginx.conf&lt;br /&gt;
      - /etc/letsencrypt/:/etc/letsencrypt/&lt;br /&gt;
      - ./local_dir/:/var/www/html/&lt;br /&gt;
      - ./local_logs/:/var/log/nginx/&lt;br /&gt;
    ports:&lt;br /&gt;
      - 80:80&lt;br /&gt;
      - 443:443&lt;br /&gt;
    restart: always&lt;br /&gt;
    logging:&lt;br /&gt;
      driver: &amp;quot;json-file&amp;quot;&lt;br /&gt;
      options:&lt;br /&gt;
        max-size: &amp;quot;200k&amp;quot;&lt;br /&gt;
        max-file: &amp;quot;10&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Here, in the local dir where docker-compose is run, the ./local_dir/ or ./local_logs will store the containers html or logs respectively. Simple. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
However, if you just have a volume, without a local directory, then it will save in /var/ somewhere (unintuitive... bad).&lt;br /&gt;
e.g. from Dolibarr:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
The Dolibarr installation and all data beyond what lives in the database&lt;br /&gt;
 (file uploads, etc) are stored in the unnamed docker volume volume&lt;br /&gt;
/var/www/html and /var/www/documents. The docker daemon will store&lt;br /&gt;
 that data within the docker directory /var/lib/docker/volumes/....&lt;br /&gt;
That means your data is saved even if the container crashes, is stopped&lt;br /&gt;
or deleted.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Specific Tips==&lt;br /&gt;
===YAML is space sensitive===&lt;br /&gt;
When you edit the .yml file for docker-compose, you have to hit spaces in a certain pattern (tabs not allowed). This is absurd, but just be aware. The errors are cryptic, and its often just because the spacing doesn't stick to what it expects.&lt;br /&gt;
===If you restart a containers namesake process, it will probably restart / reset the container===&lt;br /&gt;
So if you are troubleshooting an apache container, you edit some files, then /etc/init.d/apache2 restart, uh oh... You just undid all the edits you made, if they aren't in a permanent volume. You can shell in, make edits, and then exit the shell, but a service restart often resets the container.&lt;br /&gt;
===Consider a single reverse proxy, to handle multiple websites===&lt;br /&gt;
There are many ways to do this. I use an nginx proxy from scratch. You can also use some containers that are built for this purpose (I personally think it's bloated but a lot of people use Jason Wilder's proxy)&lt;br /&gt;
https://web.archive.org/web/https://github.com/jwilder/nginx-proxy - A lot of people swear by this, but I think it's straying too far to the high level.&lt;br /&gt;
===If you use a single reverse proxy, Lets Encrypt can be done easy===&lt;br /&gt;
In this case scenario you would have certbot on the host and a local volume that the proxy has access to which is the webroot of the Lets Encrypt scripts. The nginx proxy entry look something like this:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
location ^~ /.well-known {&lt;br /&gt;
     alias /var/www/html/.well-known/;&lt;br /&gt;
      autoindex on;&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
And this is put in every server declaration of nginx.conf. Real simple, real easy. The docker compose of the nginx proxy is something like:&lt;br /&gt;
&lt;br /&gt;
{{cat|docker-compose.yml|&lt;br /&gt;
nginx:&lt;br /&gt;
    image: nginx:latest&lt;br /&gt;
    container_name: custom_name_for_my_proxy&lt;br /&gt;
    volumes:&lt;br /&gt;
      - ./nginx.conf:/etc/nginx/nginx.conf&lt;br /&gt;
      - /etc/letsencrypt/:/etc/letsencrypt/&lt;br /&gt;
      - ./webroot/:/var/www/html/&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
The volumes section is extremely simple, don't be scared. There are two entries. Local and remote. You specify what folder will be the local directory which will be cloned to the host at the remote path you specify. So, the host runs certbot at /etc/letsencrypt, and this folder is cloned to the nginx proxy container, at the same location. Finally, webroot must be set in certbot, but it prompts you for this. And if you forget or get it wrong, it can be configured somewhere in /etc/letsencrypt. it's a one liner text entry).&lt;br /&gt;
&lt;br /&gt;
===Give every Container a Containername===&lt;br /&gt;
This makes it easier to refer to them later. All you need to do in the compose file is include container\_name: something. Much better than the gibberish they give these names if you don't include it.&lt;br /&gt;
===Beware of Interrupting Initting Containers===&lt;br /&gt;
When you first build a container, it might take 30-60 or more seconds to do whatever it needs to do. If, before then, you restart it... It may get corrupted. This has happened to me more than once. When you are testing a new container, and it doesn't seem to work for some inexplicable reason, create a container with a new name (it will create a new one), or delete the first one, and start it again.&lt;br /&gt;
===Put Apache or Program logs from the Container in a volume that is locally accessible===&lt;br /&gt;
This means you want a volume something like ./containerA\_files/logs:/var/www/log/apache2/ so that you can monitor the logs from your host machine easily. docker logs doesn't have everything.&lt;br /&gt;
===Only Restart Containers you need to Restart===&lt;br /&gt;
You can restart everything with docker-compose restart, but it's faster, and less prone to break initting containers, if you docker restart containername. Do the latter.&lt;br /&gt;
===Volumes Mounting Over Existing Directories===&lt;br /&gt;
As discussed here: https://web.archive.org/web/https://github.com/moby/moby/issues/4361, if you add a volume to an existing container, it will seem to delete the folder's contents. I've seen mixed behaviour with this. Sometimes it deletes it even if you start a new container with the folder... Other times it has not. In any case, just docker cp the files to the folder, then add the volume mount. This may not be the most graceful solution for upgrades, but it will work. Best practices would be here (See: dbxt commented Dec 14, 2014): https://web.archive.org/web/https://github.com/docker-library/wordpress/issues/10&lt;br /&gt;
===If you edit a docker-compose file you must restart the container with Docker-compose===&lt;br /&gt;
If you make a change in docker compose, you must docker stop service, then docker-compose up -d service. Otherwise the changes will not take effect. The mistake here, would be thinking that you could just docker stop service, then docker start service... That doesn't work.&lt;br /&gt;
===Keep verbose logging off your HDD with RAM only logging===&lt;br /&gt;
If you have e.g. apache/nginx write to your HDD with every website visit, it will quickly wear out your HDD (esp. SSD). Put verbose logging in the RAM only with a tmpfs mount. https://docs.docker.com/storage/tmpfs/&lt;br /&gt;
&lt;br /&gt;
e.g. (ref: https://stackoverflow.com/questions/41902930/docker-compose-tmpfs-not-working)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
services:&lt;br /&gt;
  ubuntu:&lt;br /&gt;
    image: ubuntu&lt;br /&gt;
    command: &amp;quot;bash -c 'mount'&amp;quot;&lt;br /&gt;
    volumes:&lt;br /&gt;
      - cache_vol:/var/cache&lt;br /&gt;
      - run_vol:/run&lt;br /&gt;
&lt;br /&gt;
volumes:&lt;br /&gt;
  run_vol:&lt;br /&gt;
    driver_opts:&lt;br /&gt;
      type: tmpfs&lt;br /&gt;
      device: tmpfs&lt;br /&gt;
  cache_vol:&lt;br /&gt;
    driver_opts:&lt;br /&gt;
      type: tmpfs&lt;br /&gt;
      device: tmpfs&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This also allows you to share the tmpfs mounts if needed.&lt;br /&gt;
&lt;br /&gt;
Access it from host via:&lt;br /&gt;
 docker exec -it nginx_server tail -F /run/shm/access.log&lt;br /&gt;
Note that you might think you can do&lt;br /&gt;
 docker container run my_nginx_server tail -F /run/shm/access.log&lt;br /&gt;
But that will only work on container base images, not running containers. To 'execute' a command on a running or existing container, the command you want is exec. (Also used to interactively start bash shell above)&lt;br /&gt;
&lt;br /&gt;
EDIT: Use with discretion. Active data in RAM may use power.&lt;br /&gt;
&lt;br /&gt;
===Mysql Backup / Restore===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# Backup&lt;br /&gt;
docker exec CONTAINER /usr/bin/mysqldump -u root --password=root DATABASE &amp;gt; backup.sql&lt;br /&gt;
&lt;br /&gt;
# Restore&lt;br /&gt;
cat backup.sql | docker exec -i CONTAINER /usr/bin/mysql -u root --password=root DATABASE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
ref: https://gist.github.com/spalladino/6d981f7b33f6e0afe6bb&lt;br /&gt;
May not need to do this, if you keep the DB (ibdata files) in a local directory/volume via docker-compose.yml&lt;br /&gt;
e.g.&lt;br /&gt;
 mydb:&lt;br /&gt;
    image: mysql:9999&lt;br /&gt;
    volumes:&lt;br /&gt;
       - ./db_files:/var/lib/mysql&lt;br /&gt;
    restart: always&lt;br /&gt;
&lt;br /&gt;
===Limit docker logs===&lt;br /&gt;
Docker will keep lots of logs if you don't manage it.&lt;br /&gt;
https://github.com/docker/compose/issues/1083&lt;br /&gt;
https://docs.docker.com/compose/compose-file/#logging&lt;br /&gt;
https://stackoverflow.com/questions/31829587/docker-container-logs-taking-all-my-disk-space&lt;br /&gt;
view (all) logs with &lt;br /&gt;
 docker-compose logs&lt;br /&gt;
To limit a service's logs in docker-compose do the following:&lt;br /&gt;
* find a containers/services entry&lt;br /&gt;
* append to the end (watch the white space &amp;amp; no tabs)&lt;br /&gt;
     logging:&lt;br /&gt;
       driver: &amp;quot;json-file&amp;quot;&lt;br /&gt;
       options:&lt;br /&gt;
         max-size: &amp;quot;200k&amp;quot;&lt;br /&gt;
         max-file: &amp;quot;10&amp;quot;&lt;br /&gt;
The rule with logs, is nothing - unless you need it. Then everything. Any unnecessary logging is taxing the CPU / HDD.&lt;br /&gt;
Which leads me to...&lt;br /&gt;
&lt;br /&gt;
===view details about container===&lt;br /&gt;
To view paths, configuration settings, etc...&lt;br /&gt;
See&lt;br /&gt;
 docker inspect &amp;lt;name or id&amp;gt;&lt;br /&gt;
It's easier to grep these. the search in less wasn't working for me to find .LogPath for example.&lt;br /&gt;
 docker inspect mycontainer | grep log&lt;br /&gt;
Will show where the log files are located.&lt;br /&gt;
&lt;br /&gt;
===Installing Docker-compose from pip or github binary not Debian===&lt;br /&gt;
Subject. See official docker documentation which states the URL of&lt;br /&gt;
github.com/docker/compose/releases or pip.&lt;br /&gt;
&lt;br /&gt;
Pip is probably better.&lt;br /&gt;
 apt-get install python3-pip &lt;br /&gt;
 pip3 install docker-compose&lt;br /&gt;
&lt;br /&gt;
==Troubleshooting==&lt;br /&gt;
===Cannot start container: [0] Id already in use #20570===&lt;br /&gt;
* https://github.com/moby/moby/issues/20570&lt;br /&gt;
After update, unable to start container. Solution was found to be:&lt;br /&gt;
 docker-compose down -v then docker-compose up -d&lt;br /&gt;
Container was viewable with&lt;br /&gt;
 docker ps -a (not just docker ps)&lt;br /&gt;
==Poor Design==&lt;br /&gt;
===Creating a docker-compose with a stable or latest tag===&lt;br /&gt;
If you make a docker-compose file, you should link it to a marked version. You can later edit it, to use stable or latest, but one of the strengths of Docker is version control. If you create a docker-compose, always test on a specific version, should you need to roll back in the future. Otherwise, your scripts will fail in 2-20-200 years when the conf files are not supported anymore.&lt;br /&gt;
&lt;br /&gt;
e.g. https://github.com/nucreativa/frontaccounting-docker   (6th commit)&lt;br /&gt;
Here, the nginx config is no longer supported in vhosts, it must be in server_blocks. This would've been avoided by denoting a fixed nginx release instead of tag:latest.&lt;br /&gt;
&lt;br /&gt;
==See Also==&lt;br /&gt;
&lt;br /&gt;
* [[samba_docker_by_dlandon]]&lt;br /&gt;
* [[zencart_docker_compose]]&lt;br /&gt;
&lt;br /&gt;
==External Links==&lt;br /&gt;
* https://github.com/LeCoupa/awesome-cheatsheets/blob/master/tools/docker.sh Information dense cheatsheet (unfortunately github)&lt;br /&gt;
* https://gist.github.com/spalladino/6d981f7b33f6e0afe6bb A million idiots type &amp;quot;thanks&amp;quot;. Also the source for the mysql backup command.&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
{{GNU\Linux}}&lt;/div&gt;</summary>
		<author><name>Adminguy</name></author>
	</entry>
	<entry>
		<id>http://steakwiki.com/index.php?title=Docker&amp;diff=1006</id>
		<title>Docker</title>
		<link rel="alternate" type="text/html" href="http://steakwiki.com/index.php?title=Docker&amp;diff=1006"/>
		<updated>2021-09-09T16:11:02Z</updated>

		<summary type="html">&lt;p&gt;Adminguy: /* Docker Commands */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;small&amp;gt;Docker is a type of virtualization for Gnu\Linux that allows programs to run and share similar resources, without having a full OS for each image, but while still isolating each 'vm'.&lt;br /&gt;
&lt;br /&gt;
==General Tips==&lt;br /&gt;
It helps to read a book, and then keep it as a Reference. Here Using Docker By Adrian Mouat is a decent book. In fact, you should be reading books on any subject that interests you. Physical paper books, too.&lt;br /&gt;
&lt;br /&gt;
Docker is x86_64. ARM has a separate build. There is no i386.&lt;br /&gt;
&lt;br /&gt;
You will want 'some' RAM. I had 1GB on a P4 machine, and that was not enough. 4GB was enough. &lt;br /&gt;
&lt;br /&gt;
You should always use docker compose. Docker is possible to run on the command line, but with a compose file, you can write everything down in a much simpler fashion. Use compose. It's a separate install, currently. Install it. ''Seriously, just ignore the docker command lines. I consider them useless. More of a red herring for rookies.''&lt;br /&gt;
&lt;br /&gt;
===ARM is SOL===&lt;br /&gt;
I tried to use Docker on ARM, and while you might be able to install docker, you will find that images for your applications may not be there. e.g. you will find Nginx, but you won't find Gitlab. This means that docker is pretty much x86-64 only.&lt;br /&gt;
&lt;br /&gt;
==Docker Commands==&lt;br /&gt;
Here are commands you need to know. Just the necessary ones.&lt;br /&gt;
{{cmd| docker-compose up -d}} &lt;br /&gt;
 &lt;br /&gt;
Starts the containers in the docker compose file, if they aren't already started. the -d detaches from the stdout logging. You don't need to use stdout logging, you can use docker logs, but its there if you want it.&lt;br /&gt;
 {{cmd| docker ps }}&lt;br /&gt;
Lists containers running. If one fails to start, you'll see it missing from here&lt;br /&gt;
 {{cmd|docker logs &amp;lt;containername&amp;gt; }}&lt;br /&gt;
Gives you some logging output from the container. Often enough to troubleshoot. (also see tips below).&lt;br /&gt;
 {{cmd|docker exec -it &amp;lt;containername&amp;gt; /bin/bash}}&lt;br /&gt;
This will get you in a shell in the docker container. From here you can do what you need to. Most are debian, and need apt-get install less nano or whatever program you are missing. Ping is missing from possibly all containers, so if you want to test via ping, you'll have to apt-get it.&lt;br /&gt;
 {{cmd|docker-compose restart }}&lt;br /&gt;
This will restart all containers. However, I don't recommend it. Initting containers can get corrupted this way, and also its much easier to restart a single faulty container via...&lt;br /&gt;
 {{cmd|docker restart &amp;lt;containername&amp;gt; }}&lt;br /&gt;
This will restart one single container.&lt;br /&gt;
 {{cmd|docker cp &amp;lt;containername&amp;gt;:/dir/to/file dest }}&lt;br /&gt;
You can copy files from local machine to docker, or vice versa with this. Extremely useful.&lt;br /&gt;
&lt;br /&gt;
===Deleting Containers===&lt;br /&gt;
Less often, you might want to know &lt;br /&gt;
{{cmd|&lt;br /&gt;
 #!/bin/bash&lt;br /&gt;
 docker rm $(docker ps -a -q)&lt;br /&gt;
 docker rmi $(docker images -q) --force}}&lt;br /&gt;
&lt;br /&gt;
This starts over from scratch. This is how easy it is to reboot a docker from square one.  note: below command (rmi), only needed if you want to remove base images. Needed when updating a stable. Not needed when changing other parameters not related to base image. Also, this deletes all containers, which maybe you don't want to do, if you either A) only want to delete certain images you are testing B) have some containers with custom changes saved, and not backed up elsewhere.&lt;br /&gt;
&lt;br /&gt;
===Updating===&lt;br /&gt;
 docker images&lt;br /&gt;
 (shows out of date image)&lt;br /&gt;
 docker pull mysql&lt;br /&gt;
 (downloads new image)&lt;br /&gt;
 docker images&lt;br /&gt;
 (shows two versions of mysql. old and new)&lt;br /&gt;
 docker stop some_container_name&lt;br /&gt;
 docker rmi -f cjklfs23404&lt;br /&gt;
 (where cjklfs23404 is the old container alias under docker images)&lt;br /&gt;
 docker-compose up -d mysql&lt;br /&gt;
&lt;br /&gt;
====Containers don't all Restart?!====&lt;br /&gt;
Make sure to have in your docker compose for each container a '''restart:always'''&lt;br /&gt;
Otherwise, a container won't necessarily start when docker is restarted.&lt;br /&gt;
&lt;br /&gt;
===Search for images===&lt;br /&gt;
 docker search &amp;lt;imagename&amp;gt;&lt;br /&gt;
====Search for Versions of an image====&lt;br /&gt;
What if you want to see what versions are available for a given image? Say you want php, but don't know which to get. hub.docker.com is broken. Requires js, slow, and bad. You can't get a list of images on it easily. &lt;br /&gt;
&lt;br /&gt;
Solution:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
#https://stackoverflow.com/questions/28320134/how-can-i-list-all-tags-for-a-docker-image-on-a-remote-registry&lt;br /&gt;
#$1 means&lt;br /&gt;
#first parameter you pass to this script will be searched&lt;br /&gt;
#e.g. working: debian&lt;br /&gt;
#note: some have multiple layers&lt;br /&gt;
#e.g. gitea/gitea is literally entered as $1 == gitea/gitea  (teste, working)&lt;br /&gt;
# while debian is just debian. so be aware.&lt;br /&gt;
&lt;br /&gt;
wget -q https://registry.hub.docker.com/v1/repositories/$1/tags -O -  \&lt;br /&gt;
| sed -e 's/[][]//g' -e 's/&amp;quot;//g' -e 's/ //g' | tr '}' '\n'  | awk -F: '{print $3}'&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Ref: https://stackoverflow.com/questions/54418542/dockerhub-listing-all-available-versions-of-a-given-image&lt;br /&gt;
&lt;br /&gt;
https://stackoverflow.com/questions/28320134/how-can-i-list-all-tags-for-a-docker-image-on-a-remote-registry&lt;br /&gt;
&lt;br /&gt;
===Save Changes to Docker Image===&lt;br /&gt;
 docker commit&lt;br /&gt;
See official documentation.&lt;br /&gt;
&lt;br /&gt;
===Set IP Address on docker-compose===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 mariadb:&lt;br /&gt;
    image: mariadb:10&lt;br /&gt;
    container_name: mariadb&lt;br /&gt;
    command:&lt;br /&gt;
       - mysqld&lt;br /&gt;
       - --character-set-server=utf8&lt;br /&gt;
       - --collation-server=utf8_bin&lt;br /&gt;
    environment:&lt;br /&gt;
      - MYSQL_ROOT_PASSWORD=admin&lt;br /&gt;
      - MARIADB_DATABASE=guy&lt;br /&gt;
      - MARIADB_USER=user&lt;br /&gt;
      - MARIADB_PASSWORD=passwd&lt;br /&gt;
    volumes:&lt;br /&gt;
      - ./mariadb/appdata:/var/lib/mysql&lt;br /&gt;
      - ./mariadb/config:/etc/mysql&lt;br /&gt;
    networks:&lt;br /&gt;
      somenamefornetwork:&lt;br /&gt;
        ipv4_address: 192.168.12.11&lt;br /&gt;
    ports:&lt;br /&gt;
      - &amp;quot;10055:3306&amp;quot;&lt;br /&gt;
&lt;br /&gt;
networks:&lt;br /&gt;
  somenamefornetwork:&lt;br /&gt;
    ipam:&lt;br /&gt;
      driver: default&lt;br /&gt;
      config:&lt;br /&gt;
        - subnet: &amp;quot;192.168.12.0/24&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Add the networks section to each container.&lt;br /&gt;
&lt;br /&gt;
==Dockerfile==&lt;br /&gt;
Dockerfiles and compose are slightly confusing. Sometimes you see images run an entrypoint script, sometimes not. In any case, Dockerfiles are fundamental to reproducible builds.&lt;br /&gt;
&lt;br /&gt;
Basic usage is:&lt;br /&gt;
* Docker-compose builds container from dockerfile (say you start with alpine, and install some programs)&lt;br /&gt;
* that container you built is used from thence on. &lt;br /&gt;
* if you want to change dockerfile, make changes and you must call docker-compose up --build otherwise, it will use the old container&lt;br /&gt;
&lt;br /&gt;
For a basic apache server, you might call the following in a cmd at the end of the dockerfile:&lt;br /&gt;
 CMD [&amp;quot;/usr/sbin/apache2&amp;quot;, &amp;quot;-D&amp;quot;, &amp;quot;FOREGROUND&amp;quot;]&lt;br /&gt;
When in doubt, work off of existing examples.&lt;br /&gt;
&lt;br /&gt;
==Volumes==&lt;br /&gt;
Volumes can be handled at least two ways. The simplest is to store files in a local directory which is then mapped to the remote drive.&lt;br /&gt;
&lt;br /&gt;
e.g. docker-compose:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  nginx:&lt;br /&gt;
    image: nginx:####&lt;br /&gt;
    container_name: mynginxserver&lt;br /&gt;
    volumes:&lt;br /&gt;
      - ./nginx.conf:/etc/nginx/nginx.conf&lt;br /&gt;
      - /etc/letsencrypt/:/etc/letsencrypt/&lt;br /&gt;
      - ./local_dir/:/var/www/html/&lt;br /&gt;
      - ./local_logs/:/var/log/nginx/&lt;br /&gt;
    ports:&lt;br /&gt;
      - 80:80&lt;br /&gt;
      - 443:443&lt;br /&gt;
    restart: always&lt;br /&gt;
    logging:&lt;br /&gt;
      driver: &amp;quot;json-file&amp;quot;&lt;br /&gt;
      options:&lt;br /&gt;
        max-size: &amp;quot;200k&amp;quot;&lt;br /&gt;
        max-file: &amp;quot;10&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Here, in the local dir where docker-compose is run, the ./local_dir/ or ./local_logs will store the containers html or logs respectively. Simple. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
However, if you just have a volume, without a local directory, then it will save in /var/ somewhere (unintuitive... bad).&lt;br /&gt;
e.g. from Dolibarr:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
The Dolibarr installation and all data beyond what lives in the database&lt;br /&gt;
 (file uploads, etc) are stored in the unnamed docker volume volume&lt;br /&gt;
/var/www/html and /var/www/documents. The docker daemon will store&lt;br /&gt;
 that data within the docker directory /var/lib/docker/volumes/....&lt;br /&gt;
That means your data is saved even if the container crashes, is stopped&lt;br /&gt;
or deleted.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Specific Tips==&lt;br /&gt;
===YAML is space sensitive===&lt;br /&gt;
When you edit the .yml file for docker-compose, you have to hit spaces in a certain pattern (tabs not allowed). This is absurd, but just be aware. The errors are cryptic, and its often just because the spacing doesn't stick to what it expects.&lt;br /&gt;
===If you restart a containers namesake process, it will probably restart / reset the container===&lt;br /&gt;
So if you are troubleshooting an apache container, you edit some files, then /etc/init.d/apache2 restart, uh oh... You just undid all the edits you made, if they aren't in a permanent volume. You can shell in, make edits, and then exit the shell, but a service restart often resets the container.&lt;br /&gt;
===Consider a single reverse proxy, to handle multiple websites===&lt;br /&gt;
There are many ways to do this. I use an nginx proxy from scratch. You can also use some containers that are built for this purpose (I personally think it's bloated but a lot of people use Jason Wilder's proxy)&lt;br /&gt;
https://web.archive.org/web/https://github.com/jwilder/nginx-proxy - A lot of people swear by this, but I think it's straying too far to the high level.&lt;br /&gt;
===If you use a single reverse proxy, Lets Encrypt can be done easy===&lt;br /&gt;
In this case scenario you would have certbot on the host and a local volume that the proxy has access to which is the webroot of the Lets Encrypt scripts. The nginx proxy entry look something like this:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
location ^~ /.well-known {&lt;br /&gt;
     alias /var/www/html/.well-known/;&lt;br /&gt;
      autoindex on;&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
And this is put in every server declaration of nginx.conf. Real simple, real easy. The docker compose of the nginx proxy is something like:&lt;br /&gt;
&lt;br /&gt;
{{cat|docker-compose.yml|&lt;br /&gt;
nginx:&lt;br /&gt;
    image: nginx:latest&lt;br /&gt;
    container_name: custom_name_for_my_proxy&lt;br /&gt;
    volumes:&lt;br /&gt;
      - ./nginx.conf:/etc/nginx/nginx.conf&lt;br /&gt;
      - /etc/letsencrypt/:/etc/letsencrypt/&lt;br /&gt;
      - ./webroot/:/var/www/html/&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
The volumes section is extremely simple, don't be scared. There are two entries. Local and remote. You specify what folder will be the local directory which will be cloned to the host at the remote path you specify. So, the host runs certbot at /etc/letsencrypt, and this folder is cloned to the nginx proxy container, at the same location. Finally, webroot must be set in certbot, but it prompts you for this. And if you forget or get it wrong, it can be configured somewhere in /etc/letsencrypt. it's a one liner text entry).&lt;br /&gt;
&lt;br /&gt;
===Give every Container a Containername===&lt;br /&gt;
This makes it easier to refer to them later. All you need to do in the compose file is include container\_name: something. Much better than the gibberish they give these names if you don't include it.&lt;br /&gt;
===Beware of Interrupting Initting Containers===&lt;br /&gt;
When you first build a container, it might take 30-60 or more seconds to do whatever it needs to do. If, before then, you restart it... It may get corrupted. This has happened to me more than once. When you are testing a new container, and it doesn't seem to work for some inexplicable reason, create a container with a new name (it will create a new one), or delete the first one, and start it again.&lt;br /&gt;
===Put Apache or Program logs from the Container in a volume that is locally accessible===&lt;br /&gt;
This means you want a volume something like ./containerA\_files/logs:/var/www/log/apache2/ so that you can monitor the logs from your host machine easily. docker logs doesn't have everything.&lt;br /&gt;
===Only Restart Containers you need to Restart===&lt;br /&gt;
You can restart everything with docker-compose restart, but it's faster, and less prone to break initting containers, if you docker restart containername. Do the latter.&lt;br /&gt;
===Volumes Mounting Over Existing Directories===&lt;br /&gt;
As discussed here: https://web.archive.org/web/https://github.com/moby/moby/issues/4361, if you add a volume to an existing container, it will seem to delete the folder's contents. I've seen mixed behaviour with this. Sometimes it deletes it even if you start a new container with the folder... Other times it has not. In any case, just docker cp the files to the folder, then add the volume mount. This may not be the most graceful solution for upgrades, but it will work. Best practices would be here (See: dbxt commented Dec 14, 2014): https://web.archive.org/web/https://github.com/docker-library/wordpress/issues/10&lt;br /&gt;
===If you edit a docker-compose file you must restart the container with Docker-compose===&lt;br /&gt;
If you make a change in docker compose, you must docker stop service, then docker-compose up -d service. Otherwise the changes will not take effect. The mistake here, would be thinking that you could just docker stop service, then docker start service... That doesn't work.&lt;br /&gt;
===Keep verbose logging off your HDD with RAM only logging===&lt;br /&gt;
If you have e.g. apache/nginx write to your HDD with every website visit, it will quickly wear out your HDD (esp. SSD). Put verbose logging in the RAM only with a tmpfs mount. https://docs.docker.com/storage/tmpfs/&lt;br /&gt;
&lt;br /&gt;
e.g. (ref: https://stackoverflow.com/questions/41902930/docker-compose-tmpfs-not-working)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
services:&lt;br /&gt;
  ubuntu:&lt;br /&gt;
    image: ubuntu&lt;br /&gt;
    command: &amp;quot;bash -c 'mount'&amp;quot;&lt;br /&gt;
    volumes:&lt;br /&gt;
      - cache_vol:/var/cache&lt;br /&gt;
      - run_vol:/run&lt;br /&gt;
&lt;br /&gt;
volumes:&lt;br /&gt;
  run_vol:&lt;br /&gt;
    driver_opts:&lt;br /&gt;
      type: tmpfs&lt;br /&gt;
      device: tmpfs&lt;br /&gt;
  cache_vol:&lt;br /&gt;
    driver_opts:&lt;br /&gt;
      type: tmpfs&lt;br /&gt;
      device: tmpfs&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This also allows you to share the tmpfs mounts if needed.&lt;br /&gt;
&lt;br /&gt;
Access it from host via:&lt;br /&gt;
 docker exec -it nginx_server tail -F /run/shm/access.log&lt;br /&gt;
Note that you might think you can do&lt;br /&gt;
 docker container run my_nginx_server tail -F /run/shm/access.log&lt;br /&gt;
But that will only work on container base images, not running containers. To 'execute' a command on a running or existing container, the command you want is exec. (Also used to interactively start bash shell above)&lt;br /&gt;
&lt;br /&gt;
EDIT: Use with discretion. Active data in RAM may use power.&lt;br /&gt;
&lt;br /&gt;
===Mysql Backup / Restore===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# Backup&lt;br /&gt;
docker exec CONTAINER /usr/bin/mysqldump -u root --password=root DATABASE &amp;gt; backup.sql&lt;br /&gt;
&lt;br /&gt;
# Restore&lt;br /&gt;
cat backup.sql | docker exec -i CONTAINER /usr/bin/mysql -u root --password=root DATABASE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
ref: https://gist.github.com/spalladino/6d981f7b33f6e0afe6bb&lt;br /&gt;
May not need to do this, if you keep the DB (ibdata files) in a local directory/volume via docker-compose.yml&lt;br /&gt;
e.g.&lt;br /&gt;
 mydb:&lt;br /&gt;
    image: mysql:9999&lt;br /&gt;
    volumes:&lt;br /&gt;
       - ./db_files:/var/lib/mysql&lt;br /&gt;
    restart: always&lt;br /&gt;
&lt;br /&gt;
===Limit docker logs===&lt;br /&gt;
Docker will keep lots of logs if you don't manage it.&lt;br /&gt;
https://github.com/docker/compose/issues/1083&lt;br /&gt;
https://docs.docker.com/compose/compose-file/#logging&lt;br /&gt;
https://stackoverflow.com/questions/31829587/docker-container-logs-taking-all-my-disk-space&lt;br /&gt;
view (all) logs with &lt;br /&gt;
 docker-compose logs&lt;br /&gt;
To limit a service's logs in docker-compose do the following:&lt;br /&gt;
* find a containers/services entry&lt;br /&gt;
* append to the end (watch the white space &amp;amp; no tabs)&lt;br /&gt;
     logging:&lt;br /&gt;
       driver: &amp;quot;json-file&amp;quot;&lt;br /&gt;
       options:&lt;br /&gt;
         max-size: &amp;quot;200k&amp;quot;&lt;br /&gt;
         max-file: &amp;quot;10&amp;quot;&lt;br /&gt;
The rule with logs, is nothing - unless you need it. Then everything. Any unnecessary logging is taxing the CPU / HDD.&lt;br /&gt;
Which leads me to...&lt;br /&gt;
&lt;br /&gt;
===view details about container===&lt;br /&gt;
To view paths, configuration settings, etc...&lt;br /&gt;
See&lt;br /&gt;
 docker inspect &amp;lt;name or id&amp;gt;&lt;br /&gt;
It's easier to grep these. the search in less wasn't working for me to find .LogPath for example.&lt;br /&gt;
 docker inspect mycontainer | grep log&lt;br /&gt;
Will show where the log files are located.&lt;br /&gt;
&lt;br /&gt;
===Installing Docker-compose from pip or github binary not Debian===&lt;br /&gt;
Subject. See official docker documentation which states the URL of&lt;br /&gt;
github.com/docker/compose/releases or pip.&lt;br /&gt;
&lt;br /&gt;
Pip is probably better.&lt;br /&gt;
 apt-get install python3-pip &lt;br /&gt;
 pip3 install docker-compose&lt;br /&gt;
&lt;br /&gt;
==Troubleshooting==&lt;br /&gt;
===Cannot start container: [0] Id already in use #20570===&lt;br /&gt;
* https://github.com/moby/moby/issues/20570&lt;br /&gt;
After update, unable to start container. Solution was found to be:&lt;br /&gt;
 docker-compose down -v then docker-compose up -d&lt;br /&gt;
Container was viewable with&lt;br /&gt;
 docker ps -a (not just docker ps)&lt;br /&gt;
==Poor Design==&lt;br /&gt;
===Creating a docker-compose with a stable or latest tag===&lt;br /&gt;
If you make a docker-compose file, you should link it to a marked version. You can later edit it, to use stable or latest, but one of the strengths of Docker is version control. If you create a docker-compose, always test on a specific version, should you need to roll back in the future. Otherwise, your scripts will fail in 2-20-200 years when the conf files are not supported anymore.&lt;br /&gt;
&lt;br /&gt;
e.g. https://github.com/nucreativa/frontaccounting-docker   (6th commit)&lt;br /&gt;
Here, the nginx config is no longer supported in vhosts, it must be in server_blocks. This would've been avoided by denoting a fixed nginx release instead of tag:latest.&lt;br /&gt;
&lt;br /&gt;
==See Also==&lt;br /&gt;
&lt;br /&gt;
* [[samba_docker_by_dlandon]]&lt;br /&gt;
* [[zencart_docker_compose]]&lt;br /&gt;
&lt;br /&gt;
==External Links==&lt;br /&gt;
* https://github.com/LeCoupa/awesome-cheatsheets/blob/master/tools/docker.sh Information dense cheatsheet (unfortunately github)&lt;br /&gt;
* https://gist.github.com/spalladino/6d981f7b33f6e0afe6bb A million idiots type &amp;quot;thanks&amp;quot;. Also the source for the mysql backup command.&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
{{GNU\Linux}}&lt;/div&gt;</summary>
		<author><name>Adminguy</name></author>
	</entry>
	<entry>
		<id>http://steakwiki.com/index.php?title=Computing_Fails&amp;diff=1005</id>
		<title>Computing Fails</title>
		<link rel="alternate" type="text/html" href="http://steakwiki.com/index.php?title=Computing_Fails&amp;diff=1005"/>
		<updated>2021-08-31T14:47:10Z</updated>

		<summary type="html">&lt;p&gt;Adminguy: /* Attack of the Javascript and White Space 2010's web devs! */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
==Mumbo Jumbo==&lt;br /&gt;
Programs that are full of junk or otherwise misleading. With wget, we have too much info. This example isn't specific to wget, but is a common sight. Less is more.&lt;br /&gt;
===sane/usable wget===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ wget -h&lt;br /&gt;
wget: unrecognized option: h&lt;br /&gt;
BusyBox v1.31.1 () multi-call binary.&lt;br /&gt;
&lt;br /&gt;
Usage: wget [-c|--continue] [--spider] [-q|--quiet] &lt;br /&gt;
[-O|--output-document FILE]&lt;br /&gt;
        [-o|--output-file FILE] [--header 'header: value'] [-Y|--proxy on/off]&lt;br /&gt;
        [-P DIR] [-S|--server-response] [-U|--user-agent AGENT] [-T SEC] URL...&lt;br /&gt;
&lt;br /&gt;
Retrieve files via HTTP or FTP&lt;br /&gt;
&lt;br /&gt;
        --spider        Only check URL existence: $? is 0 if exists&lt;br /&gt;
        -c              Continue retrieval of aborted transfer&lt;br /&gt;
        -q              Quiet&lt;br /&gt;
        -P DIR          Save to DIR (default .)&lt;br /&gt;
        -S              Show server response&lt;br /&gt;
        -T SEC          Network read timeout is SEC seconds&lt;br /&gt;
        -O FILE         Save to FILE ('-' for stdout)&lt;br /&gt;
        -o FILE         Log messages to FILE&lt;br /&gt;
        -U STR          Use STR for User-Agent header&lt;br /&gt;
        -Y on/off       Use proxy&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===insane/unusable wget===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ wget -h&lt;br /&gt;
GNU Wget 1.20.1, a non-interactive network retriever.&lt;br /&gt;
Usage: wget [OPTION]... [URL]...&lt;br /&gt;
&lt;br /&gt;
Mandatory arguments to long options are mandatory for short options too.&lt;br /&gt;
&lt;br /&gt;
Startup:&lt;br /&gt;
  -V,  --version                   display the version of Wget and exit&lt;br /&gt;
  -h,  --help                      print this help&lt;br /&gt;
  -b,  --background                go to background after startup&lt;br /&gt;
  -e,  --execute=COMMAND           execute a `.wgetrc'-style command&lt;br /&gt;
&lt;br /&gt;
Logging and input file:&lt;br /&gt;
  -o,  --output-file=FILE          log messages to FILE&lt;br /&gt;
  -a,  --append-output=FILE        append messages to FILE&lt;br /&gt;
  -d,  --debug                     print lots of debugging information&lt;br /&gt;
  -q,  --quiet                     quiet (no output)&lt;br /&gt;
  -v,  --verbose                   be verbose (this is the default)&lt;br /&gt;
  -nv, --no-verbose                turn off verboseness, without being quiet&lt;br /&gt;
       --report-speed=TYPE         output bandwidth as TYPE.  TYPE can be bits&lt;br /&gt;
  -i,  --input-file=FILE           download URLs found in local or external FILE&lt;br /&gt;
  -F,  --force-html                treat input file as HTML&lt;br /&gt;
  -B,  --base=URL                  resolves HTML input-file links (-i -F)&lt;br /&gt;
                                     relative to URL&lt;br /&gt;
       --config=FILE               specify config file to use&lt;br /&gt;
       --no-config                 do not read any config file&lt;br /&gt;
       --rejected-log=FILE         log reasons for URL rejection to FILE&lt;br /&gt;
&lt;br /&gt;
Download:&lt;br /&gt;
  -t,  --tries=NUMBER              set number of retries to NUMBER (0 unlimits)&lt;br /&gt;
       --retry-connrefused         retry even if connection is refused&lt;br /&gt;
       --retry-on-http-error=ERRORS    comma-separated list of HTTP errors to retry&lt;br /&gt;
  -O,  --output-document=FILE      write documents to FILE&lt;br /&gt;
  -nc, --no-clobber                skip downloads that would download to&lt;br /&gt;
                                     existing files (overwriting them)&lt;br /&gt;
       --no-netrc                  don't try to obtain credentials from .netrc&lt;br /&gt;
  -c,  --continue                  resume getting a partially-downloaded file&lt;br /&gt;
       --start-pos=OFFSET          start downloading from zero-based position OFFSET&lt;br /&gt;
       --progress=TYPE             select progress gauge type&lt;br /&gt;
       --show-progress             display the progress bar in any verbosity mode&lt;br /&gt;
  -N,  --timestamping              don't re-retrieve files unless newer than&lt;br /&gt;
                                     local&lt;br /&gt;
       --no-if-modified-since      don't use conditional if-modified-since get&lt;br /&gt;
                                     requests in timestamping mode&lt;br /&gt;
       --no-use-server-timestamps  don't set the local file's timestamp by&lt;br /&gt;
                                     the one on the server&lt;br /&gt;
  -S,  --server-response           print server response&lt;br /&gt;
       --spider                    don't download anything&lt;br /&gt;
  -T,  --timeout=SECONDS           set all timeout values to SECONDS&lt;br /&gt;
       --dns-timeout=SECS          set the DNS lookup timeout to SECS&lt;br /&gt;
       --connect-timeout=SECS      set the connect timeout to SECS&lt;br /&gt;
       --read-timeout=SECS         set the read timeout to SECS&lt;br /&gt;
  -w,  --wait=SECONDS              wait SECONDS between retrievals&lt;br /&gt;
       --waitretry=SECONDS         wait 1..SECONDS between retries of a retrieval&lt;br /&gt;
       --random-wait               wait from 0.5*WAIT...1.5*WAIT secs between retrievals&lt;br /&gt;
       --no-proxy                  explicitly turn off proxy&lt;br /&gt;
  -Q,  --quota=NUMBER              set retrieval quota to NUMBER&lt;br /&gt;
       --bind-address=ADDRESS      bind to ADDRESS (hostname or IP) on local host&lt;br /&gt;
       --limit-rate=RATE           limit download rate to RATE&lt;br /&gt;
       --no-dns-cache              disable caching DNS lookups&lt;br /&gt;
       --restrict-file-names=OS    restrict chars in file names to ones OS allows&lt;br /&gt;
       --ignore-case               ignore case when matching files/directories&lt;br /&gt;
  -4,  --inet4-only                connect only to IPv4 addresses&lt;br /&gt;
  -6,  --inet6-only                connect only to IPv6 addresses&lt;br /&gt;
       --prefer-family=FAMILY      connect first to addresses of specified family,&lt;br /&gt;
                                     one of IPv6, IPv4, or none&lt;br /&gt;
       --user=USER                 set both ftp and http user to USER&lt;br /&gt;
       --password=PASS             set both ftp and http password to PASS&lt;br /&gt;
       --ask-password              prompt for passwords&lt;br /&gt;
       --use-askpass=COMMAND       specify credential handler for requesting&lt;br /&gt;
                                     username and password.  If no COMMAND is&lt;br /&gt;
                                     specified the WGET_ASKPASS or the SSH_ASKPASS&lt;br /&gt;
                                     environment variable is used.&lt;br /&gt;
       --no-iri                    turn off IRI support&lt;br /&gt;
       --local-encoding=ENC        use ENC as the local encoding for IRIs&lt;br /&gt;
       --remote-encoding=ENC       use ENC as the default remote encoding&lt;br /&gt;
       --unlink                    remove file before clobber&lt;br /&gt;
       --xattr                     turn on storage of metadata in extended file attributes&lt;br /&gt;
Directories:&lt;br /&gt;
  -nd, --no-directories            don't create directories&lt;br /&gt;
  -x,  --force-directories         force creation of directories&lt;br /&gt;
  -nH, --no-host-directories       don't create host directories&lt;br /&gt;
       --protocol-directories      use protocol name in directories&lt;br /&gt;
  -P,  --directory-prefix=PREFIX   save files to PREFIX/..&lt;br /&gt;
       --cut-dirs=NUMBER           ignore NUMBER remote directory components&lt;br /&gt;
&lt;br /&gt;
HTTP options:&lt;br /&gt;
       --http-user=USER            set http user to USER&lt;br /&gt;
       --http-password=PASS        set http password to PASS&lt;br /&gt;
       --no-cache                  disallow server-cached data&lt;br /&gt;
       --default-page=NAME         change the default page name (normally&lt;br /&gt;
                                     this is 'index.html'.)&lt;br /&gt;
  -E,  --adjust-extension          save HTML/CSS documents with proper extensions&lt;br /&gt;
       --ignore-length             ignore 'Content-Length' header field&lt;br /&gt;
       --header=STRING             insert STRING among the headers&lt;br /&gt;
       --compression=TYPE          choose compression, one of auto, gzip and none. (default: none)&lt;br /&gt;
       --max-redirect              maximum redirections allowed per page&lt;br /&gt;
       --proxy-user=USER           set USER as proxy username&lt;br /&gt;
       --proxy-password=PASS       set PASS as proxy password&lt;br /&gt;
       --referer=URL               include 'Referer: URL' header in HTTP request&lt;br /&gt;
       --save-headers              save the HTTP headers to file&lt;br /&gt;
  -U,  --user-agent=AGENT          identify as AGENT instead of Wget/VERSION&lt;br /&gt;
       --no-http-keep-alive        disable HTTP keep-alive (persistent connections)&lt;br /&gt;
       --no-cookies                don't use cookies&lt;br /&gt;
       --load-cookies=FILE         load cookies from FILE before session&lt;br /&gt;
       --save-cookies=FILE         save cookies to FILE after session&lt;br /&gt;
       --keep-session-cookies      load and save session (non-permanent) cookies&lt;br /&gt;
       --post-data=STRING          use the POST method; send STRING as the data&lt;br /&gt;
       --post-file=FILE            use the POST method; send contents of FILE&lt;br /&gt;
       --method=HTTPMethod         use method &amp;quot;HTTPMethod&amp;quot; in the request&lt;br /&gt;
       --body-data=STRING          send STRING as data. --method MUST be set&lt;br /&gt;
       --body-file=FILE            send contents of FILE. --method MUST be set&lt;br /&gt;
       --content-disposition       honor the Content-Disposition header when&lt;br /&gt;
                                     choosing local file names (EXPERIMENTAL)&lt;br /&gt;
     --content-on-error          output the received content on server errors&lt;br /&gt;
       --auth-no-challenge         send Basic HTTP authentication information&lt;br /&gt;
                                     without first waiting for the server's&lt;br /&gt;
                                     challenge&lt;br /&gt;
&lt;br /&gt;
HTTPS (SSL/TLS) options:&lt;br /&gt;
       --secure-protocol=PR        choose secure protocol, one of auto, SSLv2,&lt;br /&gt;
                                     SSLv3, TLSv1, TLSv1_1, TLSv1_2 and PFS&lt;br /&gt;
       --https-only                only follow secure HTTPS links&lt;br /&gt;
       --no-check-certificate      don't validate the server's certificate&lt;br /&gt;
       --certificate=FILE          client certificate file&lt;br /&gt;
       --certificate-type=TYPE     client certificate type, PEM or DER&lt;br /&gt;
       --private-key=FILE          private key file&lt;br /&gt;
       --private-key-type=TYPE     private key type, PEM or DER&lt;br /&gt;
       --ca-certificate=FILE       file with the bundle of CAs&lt;br /&gt;
       --ca-directory=DIR          directory where hash list of CAs is stored&lt;br /&gt;
       --crl-file=FILE             file with bundle of CRLs&lt;br /&gt;
       --pinnedpubkey=FILE/HASHES  Public key (PEM/DER) file, or any number&lt;br /&gt;
                                   of base64 encoded sha256 hashes preceded by&lt;br /&gt;
                                   'sha256//' and separated by ';', to verify&lt;br /&gt;
                                   peer against&lt;br /&gt;
&lt;br /&gt;
       --ciphers=STR           Set the priority string (GnuTLS) or cipher list string (OpenSSL) directly.&lt;br /&gt;
                                   Use with care. This option overrides --secure-protocol.&lt;br /&gt;
                                   The format and syntax of this string depend on the specific SSL/TLS engine.&lt;br /&gt;
HSTS options:&lt;br /&gt;
       --no-hsts                   disable HSTS&lt;br /&gt;
       --hsts-file                 path of HSTS database (will override default)&lt;br /&gt;
FTP options:&lt;br /&gt;
       --ftp-user=USER             set ftp user to USER&lt;br /&gt;
       --ftp-password=PASS         set ftp password to PASS&lt;br /&gt;
       --no-remove-listing         don't remove '.listing' files&lt;br /&gt;
       --no-glob                   turn off FTP file name globbing&lt;br /&gt;
       --no-passive-ftp            disable the &amp;quot;passive&amp;quot; transfer mode&lt;br /&gt;
       --preserve-permissions      preserve remote file permissions&lt;br /&gt;
       --retr-symlinks             when recursing, get linked-to files (not dir)&lt;br /&gt;
&lt;br /&gt;
FTPS options:&lt;br /&gt;
       --ftps-implicit                 use implicit FTPS (default port is 990)&lt;br /&gt;
       --ftps-resume-ssl               resume the SSL/TLS session started in the control connection when&lt;br /&gt;
                                         opening a data connection&lt;br /&gt;
       --ftps-clear-data-connection    cipher the control channel only; all the data will be in plaintext&lt;br /&gt;
       --ftps-fallback-to-ftp          fall back to FTP if FTPS is not supported in the target server&lt;br /&gt;
WARC options:&lt;br /&gt;
       --warc-file=FILENAME        save request/response data to a .warc.gz file&lt;br /&gt;
       --warc-header=STRING        insert STRING into the warcinfo record&lt;br /&gt;
       --warc-max-size=NUMBER      set maximum size of WARC files to NUMBER&lt;br /&gt;
       --warc-cdx                  write CDX index files&lt;br /&gt;
       --warc-dedup=FILENAME       do not store records listed in this CDX file&lt;br /&gt;
       --no-warc-compression       do not compress WARC files with GZIP&lt;br /&gt;
       --no-warc-digests           do not calculate SHA1 digests&lt;br /&gt;
       --no-warc-keep-log          do not store the log file in a WARC record&lt;br /&gt;
       --warc-tempdir=DIRECTORY    location for temporary files created by the&lt;br /&gt;
                                     WARC writer&lt;br /&gt;
Recursive download:&lt;br /&gt;
  -r,  --recursive                 specify recursive download&lt;br /&gt;
  -l,  --level=NUMBER              maximum recursion depth (inf or 0 for infinite)&lt;br /&gt;
       --delete-after              delete files locally after downloading them&lt;br /&gt;
  -k,  --convert-links             make links in downloaded HTML or CSS point to&lt;br /&gt;
                                     local files&lt;br /&gt;
       --convert-file-only         convert the file part of the URLs only (usually known as the basename)&lt;br /&gt;
       --backups=N                 before writing file X, rotate up to N backup files&lt;br /&gt;
  -K,  --backup-converted          before converting file X, back up as X.orig&lt;br /&gt;
  -m,  --mirror                    shortcut for -N -r -l inf --no-remove-listing&lt;br /&gt;
  -p,  --page-requisites           get all images, etc. needed to display HTML page&lt;br /&gt;
       --strict-comments           turn on strict (SGML) handling of HTML comments&lt;br /&gt;
Recursive accept/reject:&lt;br /&gt;
  -A,  --accept=LIST               comma-separated list of accepted extensions&lt;br /&gt;
  -R,  --reject=LIST               comma-separated list of rejected extensions&lt;br /&gt;
       --accept-regex=REGEX        regex matching accepted URLs&lt;br /&gt;
       --reject-regex=REGEX        regex matching rejected URLs&lt;br /&gt;
       --regex-type=TYPE           regex type (posix|pcre)&lt;br /&gt;
  -D,  --domains=LIST              comma-separated list of accepted domains&lt;br /&gt;
       --exclude-domains=LIST      comma-separated list of rejected domains&lt;br /&gt;
       --follow-ftp                follow FTP links from HTML documents&lt;br /&gt;
       --follow-tags=LIST          comma-separated list of followed HTML tags&lt;br /&gt;
       --ignore-tags=LIST          comma-separated list of ignored HTML tags&lt;br /&gt;
  -H,  --span-hosts                go to foreign hosts when recursive&lt;br /&gt;
  -L,  --relative                  follow relative links only&lt;br /&gt;
  -I,  --include-directories=LIST  list of allowed directories&lt;br /&gt;
       --trust-server-names        use the name specified by the redirection&lt;br /&gt;
                                     URL's last component&lt;br /&gt;
  -X,  --exclude-directories=LIST  list of excluded directories&lt;br /&gt;
  -np, --no-parent                 don't ascend to the parent directory&lt;br /&gt;
&lt;br /&gt;
Email bug reports, questions, discussions to &amp;lt;bug-wget@gnu.org&amp;gt;&lt;br /&gt;
and/or open issues at https://savannah.gnu.org/bugs/?func=additem&amp;amp;group=wget.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
===Conclusion===&lt;br /&gt;
No human being can digest all the information in the latter. It's &lt;br /&gt;
insane. Perhaps another flag can be used for the verbose help information, but&lt;br /&gt;
for average daily usage, busybox wins here.&lt;br /&gt;
&lt;br /&gt;
==Attack of Javascript and White Space 2010's web devs!==&lt;br /&gt;
Discourse. I hate it so much. It's as if someone who had never used a forum before thought about designing forums. They then looked at all the reasonable spacing and coherent navigation offered by php forums from the 2000's, and said: &amp;quot;No, I must have more white space, and a font size that is 3 times as big. I must also make it slower, by adding superfluous javascript libraries.&amp;quot;. Thus, discourse was created: To deter people from actually using forums effectively.&lt;br /&gt;
&lt;br /&gt;
==IPv6 Is Badly Designed==&lt;br /&gt;
IPv6. It was supposed to take over IPv4 over 20 years ago (yes, people were talking about IPv6 in the year 2000). In 2020, it still hasn't. Why? Because it's crap, and everyone knows it. However, the amount of corporate money invested into it, means that it may eventually get shoved down people's throats. It's not even easy to find criticisms of the technology these days. It's all being astroturfed by shills. It's like a bad movie or video game sequel. It's worse than the original. But you can't avoid it.&lt;br /&gt;
&lt;br /&gt;
Ref: https://web.archive.org/web/20070707080506/http://tech.hellyeah.com/display_doc.phtml?id=28&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
To begin with, IPv6 will use a 128 bit address space, as compared to &lt;br /&gt;
IPv4's 32 bits. This 128 bit address is the biggest reason for IPv6. It &lt;br /&gt;
is supposed to give us plenty of IP addresses to last us well into the &lt;br /&gt;
future. However, 128 bits is overkill. Sixty-four should be more than &lt;br /&gt;
enough.&lt;br /&gt;
&lt;br /&gt;
Let's put it in terms that are easier to comprehend. We'll assume that &lt;br /&gt;
there are 15 billion people on the planet. (currently, there are only &lt;br /&gt;
6.1 billion, and the largest estimates for the next fifty years project &lt;br /&gt;
12 billion). With 128 bits per IP address, each person could have &lt;br /&gt;
2.26e28 IP addresses to themselves. If we reduce it to 64 bits, each &lt;br /&gt;
person would still have 1.2 billion addresses.&lt;br /&gt;
&lt;br /&gt;
What about the people who want to put IP addresses on every light pole, &lt;br /&gt;
mailbox, stop light and street sign? Well, there are about 148 million &lt;br /&gt;
square kilometers of land on the Earth (not including ocean). With 128 &lt;br /&gt;
bits, we have almost 2.3e20 addresses per square centimeter. If we &lt;br /&gt;
reduce that to 64 bits, each square centimeter would still have about &lt;br /&gt;
12.5 IP addresses -- more than enough.&lt;br /&gt;
&lt;br /&gt;
...(Sections Omitted)&lt;br /&gt;
&lt;br /&gt;
Part of IPv4's immense success was due to its &lt;br /&gt;
simplicity and rigid structure. It does the job it was meant to do &lt;br /&gt;
quickly and effectively. IPv6 adds all sorts of bells and whistles that &lt;br /&gt;
are unneccesary and even detrimental. With all the wasted space and &lt;br /&gt;
privacy issues, I'd rather have the IETF go back to the drawing board &lt;br /&gt;
and come back with IPv7&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Less is more. The answer isn't &amp;quot;add more people&amp;quot;. The answer isn't &amp;quot;add more ip addresses&amp;quot;. Things can't expand exponentially forever. There has to be limits in place. Just as humans will destroy themselves on Earth, so too will they screw up the internet.&lt;br /&gt;
&lt;br /&gt;
==Hidden Files==&lt;br /&gt;
 alias ls='ls -a'&lt;br /&gt;
Hidden files are evil. Either clean up your files and move to a directory or don't fill up directories with config crap. All ls should be ls -a. They will bite you as often as pcb makers get bitten by incorrect footprints. Its bad design. It will never go away. There's no thinking that you&lt;br /&gt;
should've been smarter. Lies. Its the human factor. It will always, always bite you someday.&lt;br /&gt;
Hidden files are fundamentally flawed. They will always cause trouble.&lt;br /&gt;
&lt;br /&gt;
==Duplication of Work==&lt;br /&gt;
There are dozens of companies and individuals doing source code management tools. Meta-coding. The duplication of work can't ever have been this bad, and the duplication here isn't even an actual tool: it's a tool for a tool. Go ahead and search for source code / git hosting. Prepare yourself, there are way too many options. It's to the point of hyperbole.&lt;br /&gt;
&lt;br /&gt;
Western cultures need to take a lesson from china. One of china's strengths, is not necessarily cutting corners, but in not doing more than is needed to complete a task. It's about efficiency. And it is possibly a sin to indulge in things that aren't necessary. Time and Life is short. Time management is critical.&lt;/div&gt;</summary>
		<author><name>Adminguy</name></author>
	</entry>
	<entry>
		<id>http://steakwiki.com/index.php?title=Windows_Desktop_Screenshot_Monitoring&amp;diff=1004</id>
		<title>Windows Desktop Screenshot Monitoring</title>
		<link rel="alternate" type="text/html" href="http://steakwiki.com/index.php?title=Windows_Desktop_Screenshot_Monitoring&amp;diff=1004"/>
		<updated>2021-08-31T14:46:26Z</updated>

		<summary type="html">&lt;p&gt;Adminguy: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Template:ProprietarySoftware}}&lt;br /&gt;
&lt;br /&gt;
Here are notes on setting up desktop screen monitoring for Windows 10 (02/2020).&lt;br /&gt;
&lt;br /&gt;
The intention is for this to be a way to monitor users computers, in case they get a virus or do something stupid (or someone unauthorized uses the computer). It is for security and is 0.2 FPS (yes, that's 1 picture every 5 seconds). It is not intended to be a video stream of the user working.&lt;br /&gt;
&lt;br /&gt;
EDIT: 08/2021, just use Zoneminder 1.36 or 1.38 (when released). See this post which has some tips on setup:&lt;br /&gt;
https://forums.zoneminder.com/viewtopic.php?f=42&amp;amp;t=30581&amp;amp;p=120570&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==tl;dr Win10 Solution for taking Desktop Screenshots and Serving over LAN==&lt;br /&gt;
Use this powershell script&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[cmdletbinding()]            &lt;br /&gt;
param(            &lt;br /&gt;
  [string]$Width,            &lt;br /&gt;
  [string]$Height,            &lt;br /&gt;
  [String]$FileName = &amp;quot;Screenshot&amp;quot;  ,&lt;br /&gt;
  [string]$path2 = &amp;quot;c:\LOCATIONTOSAVE\&amp;quot;          &lt;br /&gt;
&lt;br /&gt;
)            &lt;br /&gt;
#Function to take screenshot. This function takes the width and height of the screen that # #has            &lt;br /&gt;
#to be captured            &lt;br /&gt;
&lt;br /&gt;
function Take-Screenshot{            &lt;br /&gt;
[cmdletbinding()]            &lt;br /&gt;
param(            &lt;br /&gt;
 [Drawing.Rectangle]$bounds,             &lt;br /&gt;
 [string]$path            &lt;br /&gt;
)             &lt;br /&gt;
   $bmp = New-Object Drawing.Bitmap $bounds.width, $bounds.height            &lt;br /&gt;
   $graphics = [Drawing.Graphics]::FromImage($bmp)            &lt;br /&gt;
   $graphics.CopyFromScreen($bounds.Location, [Drawing.Point]::Empty, $bounds.size)            &lt;br /&gt;
   $bmp.Save($path)            &lt;br /&gt;
   $graphics.Dispose()            &lt;br /&gt;
   $bmp.Dispose()            &lt;br /&gt;
}            &lt;br /&gt;
&lt;br /&gt;
#Function to get the primary monitor resolution.            &lt;br /&gt;
#This code is sourced from             &lt;br /&gt;
# https://techibee.com/powershell/powershell-script-to-get-desktop-screen-resolution/1615            &lt;br /&gt;
&lt;br /&gt;
function Get-ScreenResolution {            &lt;br /&gt;
 $Screens = [system.windows.forms.screen]::AllScreens                        &lt;br /&gt;
 foreach ($Screen in $Screens) {            &lt;br /&gt;
  $DeviceName = $Screen.DeviceName            &lt;br /&gt;
  $Width  = $Screen.Bounds.Width            &lt;br /&gt;
  $Height  = $Screen.Bounds.Height            &lt;br /&gt;
  $IsPrimary = $Screen.Primary                        &lt;br /&gt;
  $OutputObj = New-Object -TypeName PSobject            &lt;br /&gt;
  $OutputObj | Add-Member -MemberType NoteProperty -Name DeviceName -Value $DeviceName            &lt;br /&gt;
  $OutputObj | Add-Member -MemberType NoteProperty -Name Width -Value $Width            &lt;br /&gt;
  $OutputObj | Add-Member -MemberType NoteProperty -Name Height -Value $Height            &lt;br /&gt;
  $OutputObj | Add-Member -MemberType NoteProperty -Name IsPrimaryMonitor -Value $IsPrimary            &lt;br /&gt;
  $OutputObj                        &lt;br /&gt;
 }            &lt;br /&gt;
}            &lt;br /&gt;
&lt;br /&gt;
#Main script begins            &lt;br /&gt;
&lt;br /&gt;
#By default captured screenshot will be saved in %temp% folder            &lt;br /&gt;
#You can override it here if you want  &lt;br /&gt;
#orig          &lt;br /&gt;
#$Filepath = join-path $env:temp $FileName &lt;br /&gt;
#edit&lt;br /&gt;
$Filepath = join-path $path2 $FileName           &lt;br /&gt;
&lt;br /&gt;
[void] [Reflection.Assembly]::LoadWithPartialName(&amp;quot;System.Windows.Forms&amp;quot;)            &lt;br /&gt;
[void] [Reflection.Assembly]::LoadWithPartialName(&amp;quot;System.Drawing&amp;quot;)            &lt;br /&gt;
&lt;br /&gt;
if(!($width -and $height)) {            &lt;br /&gt;
&lt;br /&gt;
 $screen = Get-ScreenResolution | ? {$_.IsPrimaryMonitor -eq $true}            &lt;br /&gt;
 $Width = $screen.Width            &lt;br /&gt;
 $Height = $screen.height            &lt;br /&gt;
}            &lt;br /&gt;
&lt;br /&gt;
$bounds = [Drawing.Rectangle]::FromLTRB(0, 0, $Screen.Width, $Screen.Height)            &lt;br /&gt;
&lt;br /&gt;
Take-Screenshot -Bounds $bounds -Path &amp;quot;$Filepath.png&amp;quot;            &lt;br /&gt;
#Now you have the screenshot&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Call it every 1 minute in task scheduler with this .vbs script (must use vbs to be quiet, and not open a cmd window)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Dim index, count&lt;br /&gt;
count = 11&lt;br /&gt;
For index = 1 To count&lt;br /&gt;
 command = &amp;quot;powershell.exe -nologo -command C:\SCRIPTHERE&amp;quot;&lt;br /&gt;
 set shell = CreateObject(&amp;quot;WScript.Shell&amp;quot;)&lt;br /&gt;
 shell.Run command,0&lt;br /&gt;
'this is in milliseconds&lt;br /&gt;
 WScript.Sleep 5000&lt;br /&gt;
Next&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In order for this type of script to take a screenshot, it must run as the user &amp;quot;only when he is logged in&amp;quot; per the task scheduler settings. Do not run this in task scheduler as SYSTEM, or whether or not the user is logged in. See details below.&lt;br /&gt;
&lt;br /&gt;
===Grab Images via SMB===&lt;br /&gt;
At this point, you have an updating file which is a screenshot. You can now grab this however you want. If you use something like Zoneminder (which can read an image file as a video stream) or Blue Iris (not sure if that can, but probably), you will have a video stream.&lt;br /&gt;
&lt;br /&gt;
Map the SMB drive to the recording server to grab the file without installing anything. Another option is to use apache w/authentication (or without).&lt;br /&gt;
&lt;br /&gt;
==Details==&lt;br /&gt;
===VLC works in Win7 Only===&lt;br /&gt;
In Windows 7 (I think) you can simply use VLC from the command line.&lt;br /&gt;
ref: https://www.axis.com/files/tech_notes/Desktop_MJPEG_Screen_Capture.pdf&lt;br /&gt;
 &amp;quot;C:\Program Files\VideoLAN\VLC\vlc.exe&amp;quot; -I --dummy-quiet screen://  --screen-fps=3   :sout=#transcode{vcodec=MJPG,venc=ffmpeg{qmin=0,qmax=10},vb=800,width=320, height=240,acodec=none}:http{mux=mpjpeg,dst=:8088} :sout-keep&lt;br /&gt;
&lt;br /&gt;
This was tested to work in 2008 server. (NOTE: Doesn't work in win10, without opening a video screen. see below.)&lt;br /&gt;
&lt;br /&gt;
NOTE: make sure to open port in firewall.&lt;br /&gt;
&lt;br /&gt;
test first in localhost on server.&lt;br /&gt;
&lt;br /&gt;
then test remotely. &lt;br /&gt;
&lt;br /&gt;
firewall needs port opened for remote access.&lt;br /&gt;
&lt;br /&gt;
Let's look at other options.&lt;br /&gt;
&lt;br /&gt;
 https://github.com/aviloria/ScreenCaptureServer/releases&lt;br /&gt;
&lt;br /&gt;
 https://github.com/rdp/screen-capture-recorder-to-video-windows-free&lt;br /&gt;
this just looks like a mess. popular, though. doesn't mean anything.&lt;br /&gt;
&lt;br /&gt;
===Manual JPEG screen capture and server over HTTP for Win10===&lt;br /&gt;
&lt;br /&gt;
After all that, I decided the best solution is to do this manually.&lt;br /&gt;
Almost future proof.&lt;br /&gt;
&lt;br /&gt;
Some apache server, with a program that just takes screenshots and puts them in the local dir. You can bypass the apache server by using SMB, also. That avoids the need to install apache.&lt;br /&gt;
&lt;br /&gt;
Then Zoneminder, Blueiris, etc... server reads the file.&lt;br /&gt;
&lt;br /&gt;
I tried autoscreen (sourceforge)&lt;br /&gt;
av gives warnings on autoscreen, which must be wrong.&lt;br /&gt;
&lt;br /&gt;
It doesn't really work because, it saves to a new file all the time. I gave up at this point. Didn't look into this.&lt;br /&gt;
&lt;br /&gt;
====Powershell Get Screenshot====&lt;br /&gt;
I tried a few things, before finding one that worked.&lt;br /&gt;
&lt;br /&gt;
You may to need to allow scripts (or pass the allow to the script in the&lt;br /&gt;
powershell, i.e. bypassing the execution policy), so:&lt;br /&gt;
* https://www.tenforums.com/tutorials/54585-change-powershell-script-execution-policy-windows-10-a.html&lt;br /&gt;
explains it well&lt;br /&gt;
&lt;br /&gt;
 Set-ExecutionPolicy RemoteSigned -Scope CurrentUser -Force&lt;br /&gt;
&lt;br /&gt;
EDIT: Don't set -Scope current user or you will have to disable it later.&lt;br /&gt;
It's an entangled set of sub-permissions and if you enable some of them, you can't change the main ones. The scope is sub permissions, RemoteSigned&lt;br /&gt;
being one of the main permissions.&lt;br /&gt;
&lt;br /&gt;
Keep in mind when saving png, that you may have to write somewhere other than c: which often doesn't have write permissions anymore.&lt;br /&gt;
&lt;br /&gt;
that didn't work&lt;br /&gt;
trying a different one...&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[cmdletbinding()]            &lt;br /&gt;
param(            &lt;br /&gt;
  [string]$Width,            &lt;br /&gt;
  [string]$Height,            &lt;br /&gt;
  [String]$FileName = &amp;quot;Screenshot&amp;quot;  ,&lt;br /&gt;
  [string]$path2 = &amp;quot;c:\LOCATIONTOSAVE\&amp;quot;          &lt;br /&gt;
&lt;br /&gt;
)            &lt;br /&gt;
#Function to take screenshot. This function takes the width and height of the screen that # #has            &lt;br /&gt;
#to be captured            &lt;br /&gt;
&lt;br /&gt;
function Take-Screenshot{            &lt;br /&gt;
[cmdletbinding()]            &lt;br /&gt;
param(            &lt;br /&gt;
 [Drawing.Rectangle]$bounds,             &lt;br /&gt;
 [string]$path            &lt;br /&gt;
)             &lt;br /&gt;
   $bmp = New-Object Drawing.Bitmap $bounds.width, $bounds.height            &lt;br /&gt;
   $graphics = [Drawing.Graphics]::FromImage($bmp)            &lt;br /&gt;
   $graphics.CopyFromScreen($bounds.Location, [Drawing.Point]::Empty, $bounds.size)            &lt;br /&gt;
   $bmp.Save($path)            &lt;br /&gt;
   $graphics.Dispose()            &lt;br /&gt;
   $bmp.Dispose()            &lt;br /&gt;
}            &lt;br /&gt;
&lt;br /&gt;
#Function to get the primary monitor resolution.            &lt;br /&gt;
#This code is sourced from             &lt;br /&gt;
# https://techibee.com/powershell/powershell-script-to-get-desktop-screen-resolution/1615            &lt;br /&gt;
&lt;br /&gt;
function Get-ScreenResolution {            &lt;br /&gt;
 $Screens = [system.windows.forms.screen]::AllScreens                        &lt;br /&gt;
 foreach ($Screen in $Screens) {            &lt;br /&gt;
  $DeviceName = $Screen.DeviceName            &lt;br /&gt;
  $Width  = $Screen.Bounds.Width            &lt;br /&gt;
  $Height  = $Screen.Bounds.Height            &lt;br /&gt;
  $IsPrimary = $Screen.Primary                        &lt;br /&gt;
  $OutputObj = New-Object -TypeName PSobject            &lt;br /&gt;
  $OutputObj | Add-Member -MemberType NoteProperty -Name DeviceName -Value $DeviceName            &lt;br /&gt;
  $OutputObj | Add-Member -MemberType NoteProperty -Name Width -Value $Width            &lt;br /&gt;
  $OutputObj | Add-Member -MemberType NoteProperty -Name Height -Value $Height            &lt;br /&gt;
  $OutputObj | Add-Member -MemberType NoteProperty -Name IsPrimaryMonitor -Value $IsPrimary            &lt;br /&gt;
  $OutputObj                        &lt;br /&gt;
 }            &lt;br /&gt;
}            &lt;br /&gt;
&lt;br /&gt;
#Main script begins            &lt;br /&gt;
&lt;br /&gt;
#By default captured screenshot will be saved in %temp% folder            &lt;br /&gt;
#You can override it here if you want  &lt;br /&gt;
#orig          &lt;br /&gt;
#$Filepath = join-path $env:temp $FileName &lt;br /&gt;
#edit&lt;br /&gt;
$Filepath = join-path $path2 $FileName           &lt;br /&gt;
&lt;br /&gt;
[void] [Reflection.Assembly]::LoadWithPartialName(&amp;quot;System.Windows.Forms&amp;quot;)            &lt;br /&gt;
[void] [Reflection.Assembly]::LoadWithPartialName(&amp;quot;System.Drawing&amp;quot;)            &lt;br /&gt;
&lt;br /&gt;
if(!($width -and $height)) {            &lt;br /&gt;
&lt;br /&gt;
 $screen = Get-ScreenResolution | ? {$_.IsPrimaryMonitor -eq $true}            &lt;br /&gt;
 $Width = $screen.Width            &lt;br /&gt;
 $Height = $screen.height            &lt;br /&gt;
}            &lt;br /&gt;
&lt;br /&gt;
$bounds = [Drawing.Rectangle]::FromLTRB(0, 0, $Screen.Width, $Screen.Height)            &lt;br /&gt;
&lt;br /&gt;
Take-Screenshot -Bounds $bounds -Path &amp;quot;$Filepath.png&amp;quot;            &lt;br /&gt;
#Now you have the screenshot&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
from: https://techibee.com/powershell/powershell-script-to-take-a-screenshot-of-your-desktop/1626&lt;br /&gt;
&lt;br /&gt;
That works, but has some load on a 4 core PC from 2010.&lt;br /&gt;
Not bad, but not great. I wouldn't run it more than every 10 seconds&lt;br /&gt;
or so. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 A Windows Task Scheduler trigger cannot repeat more often than every 1 minute, but you can set up multiple triggers. To run a task every 10 seconds, add six Triggers. Each one should run the task Daily, and Repeat task every 1 minute. Their start times should be 12:00:00 AM, 12:00:10 AM, 12:00:20 AM, 12:00:30 AM, 12:00:40 AM, and 12:00:50 AM.&lt;br /&gt;
&lt;br /&gt;
from: https://superuser.com/questions/293445/windows-task-scheduler-schedule-task-to-run-once-every-10-seconds&lt;br /&gt;
&lt;br /&gt;
But it's easier to just use a for loop in a script with a delay.&lt;br /&gt;
&lt;br /&gt;
It ends up that the script that calls this in task scheduler must be vbs&lt;br /&gt;
as it must be quiet. Powershell and cmd, both open boxes, the user will see. This is because the script MUST run as the USER, when they are LOGGED IN. You can't run as system, or another admin. We are taking a screenshot of their desktop, and that env must be setup.&lt;br /&gt;
&lt;br /&gt;
The vbs script that calls the above ps1 powershell might look something like&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Dim index, count&lt;br /&gt;
count = 11&lt;br /&gt;
For index = 1 To count&lt;br /&gt;
 command = &amp;quot;powershell.exe -nologo -command C:\SCRIPTHERE&amp;quot;&lt;br /&gt;
 set shell = CreateObject(&amp;quot;WScript.Shell&amp;quot;)&lt;br /&gt;
 shell.Run command,0&lt;br /&gt;
'this is in milliseconds&lt;br /&gt;
 WScript.Sleep 5000&lt;br /&gt;
Next&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So it runs every 5 seconds for a minute. Then you set it to run in Task Scheduler. Just call it directly, no need to do anything else. Test in cmd line.&lt;br /&gt;
&lt;br /&gt;
You can adjust the PixelFormat to get smaller PNG files in the above ps1 script. I used&lt;br /&gt;
 $bmp = New-Object Drawing.Bitmap $bounds.width, $bounds.height, Format16bppRgb555&lt;br /&gt;
&lt;br /&gt;
==Improvements==&lt;br /&gt;
* Lower Resource Usage&lt;br /&gt;
* Higher FPS&lt;br /&gt;
* Encode to H264 and serve low res stream over RTSP (too bad VLC doesn't work anymore)&lt;/div&gt;</summary>
		<author><name>Adminguy</name></author>
	</entry>
	<entry>
		<id>http://steakwiki.com/index.php?title=Loops&amp;diff=1003</id>
		<title>Loops</title>
		<link rel="alternate" type="text/html" href="http://steakwiki.com/index.php?title=Loops&amp;diff=1003"/>
		<updated>2021-08-12T04:24:50Z</updated>

		<summary type="html">&lt;p&gt;Adminguy: /* read file into command line by line */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This is a basic (bash) loop to operate on files.&lt;br /&gt;
&lt;br /&gt;
Examples are given for 7z and video conversion.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/bin/bash -x&lt;br /&gt;
#for i in *.webm;&lt;br /&gt;
        for i in *.7z&lt;br /&gt;
 do name=`echo $i | cut -d'.' -f1`;&lt;br /&gt;
 echo $name;&lt;br /&gt;
&lt;br /&gt;
#for h264&lt;br /&gt;
# ffmpeg -i $i -s 1280x720 -c:a copy $name.mp4;&lt;br /&gt;
&lt;br /&gt;
#for webm&lt;br /&gt;
&lt;br /&gt;
#-map_metadata -1 is to remove metadata, at least try to remove some. (need to verify)&lt;br /&gt;
#ffmpeg -i $i -map_metadata -1 -c:v libvpx -crf 10 -b:v 1M -c:a libvorbis $name.webm&lt;br /&gt;
 7z e -o&amp;quot;$name&amp;quot; ./&amp;quot;$i&amp;quot; &lt;br /&gt;
done&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Basically, trim off extension of i, put into name. Use both for extractions/conversion.&lt;br /&gt;
&lt;br /&gt;
===Batch Edit Photos===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
for i in *.JPG&lt;br /&gt;
do&lt;br /&gt;
#delete exif data&lt;br /&gt;
mogrify -strip $i&lt;br /&gt;
#test convert size in gimp first to get ratio right&lt;br /&gt;
convert -resize 1080x810 $i ~/Desktop/photofolder/$i&lt;br /&gt;
done&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Add date:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
DATE=$(date &amp;quot;+%Y_%m_%d&amp;quot;)&lt;br /&gt;
for i in *.JPG&lt;br /&gt;
do&lt;br /&gt;
#delete exif data&lt;br /&gt;
mogrify -strip $i&lt;br /&gt;
#test convert size in gimp first to get ratio right&lt;br /&gt;
convert -resize 1080x810 $i ~/Desktop/photofolder/$DATE$i&lt;br /&gt;
done&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Interactive Range Loop===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
for i in {1..254}; &lt;br /&gt;
do &lt;br /&gt;
some program that stalls goes here;&lt;br /&gt;
done&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
this will stop at the program, if it doesn't immediately complete&lt;br /&gt;
so do this:&lt;br /&gt;
ctrl - \&lt;br /&gt;
&lt;br /&gt;
that will skip to the next range loop (i increments). note its not ctrl - c&lt;br /&gt;
which will exit script.&lt;br /&gt;
you can hold ctrl and depress \&lt;br /&gt;
&lt;br /&gt;
What is CTRL - \?&lt;br /&gt;
https://en.wikipedia.org/wiki/Signal_(IPC)&lt;br /&gt;
One of the other options besides ctrl - c. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* https://hackaday.com/2020/06/12/binary-math-tricks-shifting-to-divide-by-ten-aint-easy/&lt;br /&gt;
&lt;br /&gt;
===read file into command line by line===&lt;br /&gt;
&amp;lt;pre&amp;gt;#!/bin/bash&lt;br /&gt;
input=&amp;quot;text_file.txt&amp;quot;&lt;br /&gt;
while IFS= read -r line&lt;br /&gt;
do&lt;br /&gt;
  wget $line&lt;br /&gt;
done &amp;lt; &amp;quot;$input&amp;quot;&amp;lt;/pre&amp;gt;&lt;br /&gt;
Obviously here, wget is the command being used. This example downloads from a text file with a list of URLs.&lt;/div&gt;</summary>
		<author><name>Adminguy</name></author>
	</entry>
	<entry>
		<id>http://steakwiki.com/index.php?title=Loops&amp;diff=1002</id>
		<title>Loops</title>
		<link rel="alternate" type="text/html" href="http://steakwiki.com/index.php?title=Loops&amp;diff=1002"/>
		<updated>2021-08-12T04:23:43Z</updated>

		<summary type="html">&lt;p&gt;Adminguy: /* Interactive Range Loop */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This is a basic (bash) loop to operate on files.&lt;br /&gt;
&lt;br /&gt;
Examples are given for 7z and video conversion.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/bin/bash -x&lt;br /&gt;
#for i in *.webm;&lt;br /&gt;
        for i in *.7z&lt;br /&gt;
 do name=`echo $i | cut -d'.' -f1`;&lt;br /&gt;
 echo $name;&lt;br /&gt;
&lt;br /&gt;
#for h264&lt;br /&gt;
# ffmpeg -i $i -s 1280x720 -c:a copy $name.mp4;&lt;br /&gt;
&lt;br /&gt;
#for webm&lt;br /&gt;
&lt;br /&gt;
#-map_metadata -1 is to remove metadata, at least try to remove some. (need to verify)&lt;br /&gt;
#ffmpeg -i $i -map_metadata -1 -c:v libvpx -crf 10 -b:v 1M -c:a libvorbis $name.webm&lt;br /&gt;
 7z e -o&amp;quot;$name&amp;quot; ./&amp;quot;$i&amp;quot; &lt;br /&gt;
done&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Basically, trim off extension of i, put into name. Use both for extractions/conversion.&lt;br /&gt;
&lt;br /&gt;
===Batch Edit Photos===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
for i in *.JPG&lt;br /&gt;
do&lt;br /&gt;
#delete exif data&lt;br /&gt;
mogrify -strip $i&lt;br /&gt;
#test convert size in gimp first to get ratio right&lt;br /&gt;
convert -resize 1080x810 $i ~/Desktop/photofolder/$i&lt;br /&gt;
done&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Add date:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
DATE=$(date &amp;quot;+%Y_%m_%d&amp;quot;)&lt;br /&gt;
for i in *.JPG&lt;br /&gt;
do&lt;br /&gt;
#delete exif data&lt;br /&gt;
mogrify -strip $i&lt;br /&gt;
#test convert size in gimp first to get ratio right&lt;br /&gt;
convert -resize 1080x810 $i ~/Desktop/photofolder/$DATE$i&lt;br /&gt;
done&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Interactive Range Loop===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
for i in {1..254}; &lt;br /&gt;
do &lt;br /&gt;
some program that stalls goes here;&lt;br /&gt;
done&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
this will stop at the program, if it doesn't immediately complete&lt;br /&gt;
so do this:&lt;br /&gt;
ctrl - \&lt;br /&gt;
&lt;br /&gt;
that will skip to the next range loop (i increments). note its not ctrl - c&lt;br /&gt;
which will exit script.&lt;br /&gt;
you can hold ctrl and depress \&lt;br /&gt;
&lt;br /&gt;
What is CTRL - \?&lt;br /&gt;
https://en.wikipedia.org/wiki/Signal_(IPC)&lt;br /&gt;
One of the other options besides ctrl - c. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* https://hackaday.com/2020/06/12/binary-math-tricks-shifting-to-divide-by-ten-aint-easy/&lt;br /&gt;
&lt;br /&gt;
===read file into command line by line===&lt;br /&gt;
&amp;lt;pre&amp;gt;#!/bin/bash&lt;br /&gt;
input=&amp;quot;text_file.txt&amp;quot;&lt;br /&gt;
while IFS= read -r line&lt;br /&gt;
do&lt;br /&gt;
  wget $line&lt;br /&gt;
done &amp;lt; &amp;quot;$input&amp;quot;&amp;lt;/pre&amp;gt;&lt;br /&gt;
Obviously here, wget is the command being used. Such an example being to download from a list of URLs delimited by newline.&lt;/div&gt;</summary>
		<author><name>Adminguy</name></author>
	</entry>
	<entry>
		<id>http://steakwiki.com/index.php?title=Loops&amp;diff=1001</id>
		<title>Loops</title>
		<link rel="alternate" type="text/html" href="http://steakwiki.com/index.php?title=Loops&amp;diff=1001"/>
		<updated>2021-08-12T04:23:22Z</updated>

		<summary type="html">&lt;p&gt;Adminguy: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This is a basic (bash) loop to operate on files.&lt;br /&gt;
&lt;br /&gt;
Examples are given for 7z and video conversion.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/bin/bash -x&lt;br /&gt;
#for i in *.webm;&lt;br /&gt;
        for i in *.7z&lt;br /&gt;
 do name=`echo $i | cut -d'.' -f1`;&lt;br /&gt;
 echo $name;&lt;br /&gt;
&lt;br /&gt;
#for h264&lt;br /&gt;
# ffmpeg -i $i -s 1280x720 -c:a copy $name.mp4;&lt;br /&gt;
&lt;br /&gt;
#for webm&lt;br /&gt;
&lt;br /&gt;
#-map_metadata -1 is to remove metadata, at least try to remove some. (need to verify)&lt;br /&gt;
#ffmpeg -i $i -map_metadata -1 -c:v libvpx -crf 10 -b:v 1M -c:a libvorbis $name.webm&lt;br /&gt;
 7z e -o&amp;quot;$name&amp;quot; ./&amp;quot;$i&amp;quot; &lt;br /&gt;
done&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Basically, trim off extension of i, put into name. Use both for extractions/conversion.&lt;br /&gt;
&lt;br /&gt;
===Batch Edit Photos===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
for i in *.JPG&lt;br /&gt;
do&lt;br /&gt;
#delete exif data&lt;br /&gt;
mogrify -strip $i&lt;br /&gt;
#test convert size in gimp first to get ratio right&lt;br /&gt;
convert -resize 1080x810 $i ~/Desktop/photofolder/$i&lt;br /&gt;
done&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Add date:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
DATE=$(date &amp;quot;+%Y_%m_%d&amp;quot;)&lt;br /&gt;
for i in *.JPG&lt;br /&gt;
do&lt;br /&gt;
#delete exif data&lt;br /&gt;
mogrify -strip $i&lt;br /&gt;
#test convert size in gimp first to get ratio right&lt;br /&gt;
convert -resize 1080x810 $i ~/Desktop/photofolder/$DATE$i&lt;br /&gt;
done&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Interactive Range Loop===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
for i in {1..254}; &lt;br /&gt;
do &lt;br /&gt;
some program that stalls goes here;&lt;br /&gt;
done&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
this will stop at the program, if it doesn't immediately complete&lt;br /&gt;
so do this:&lt;br /&gt;
ctrl - \&lt;br /&gt;
&lt;br /&gt;
that will skip to the next range loop (i increments). note its not ctrl - c&lt;br /&gt;
which will exit script.&lt;br /&gt;
you can hold ctrl and depress \&lt;br /&gt;
&lt;br /&gt;
What is CTRL - \?&lt;br /&gt;
https://en.wikipedia.org/wiki/Signal_(IPC)&lt;br /&gt;
One of the other options besides ctrl - c. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* https://hackaday.com/2020/06/12/binary-math-tricks-shifting-to-divide-by-ten-aint-easy/&lt;br /&gt;
&lt;br /&gt;
+==read file into command line by line==&lt;br /&gt;
&amp;lt;pre&amp;gt;#!/bin/bash&lt;br /&gt;
input=&amp;quot;text_file.txt&amp;quot;&lt;br /&gt;
while IFS= read -r line&lt;br /&gt;
do&lt;br /&gt;
  wget $line&lt;br /&gt;
done &amp;lt; &amp;quot;$input&amp;quot;&amp;lt;/pre&amp;gt;&lt;br /&gt;
Obviously here, wget is the command being used. Such an example being to download from a list of URLs delimited by newline.&lt;/div&gt;</summary>
		<author><name>Adminguy</name></author>
	</entry>
	<entry>
		<id>http://steakwiki.com/index.php?title=Alpine&amp;diff=1000</id>
		<title>Alpine</title>
		<link rel="alternate" type="text/html" href="http://steakwiki.com/index.php?title=Alpine&amp;diff=1000"/>
		<updated>2021-05-24T04:56:53Z</updated>

		<summary type="html">&lt;p&gt;Adminguy: /* Search for who owns a certain file */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;small&amp;gt;&lt;br /&gt;
==General Tips==&lt;br /&gt;
===Building a package in Alpine===&lt;br /&gt;
&lt;br /&gt;
https://wiki.alpinelinux.org/wiki/Category_talk:Developer_Documentation#Building_from_source_and_creating_packages&lt;br /&gt;
&lt;br /&gt;
https://wiki.alpinelinux.org/wiki/Custom_Kernel&lt;br /&gt;
&lt;br /&gt;
===Xorg video playback stutters upon suspend / resume===&lt;br /&gt;
&lt;br /&gt;
I added the following configuration to xorg.conf&lt;br /&gt;
 Section &amp;quot;Device&amp;quot;&lt;br /&gt;
   Identifier &amp;quot;Intel Graphics&amp;quot;&lt;br /&gt;
   Driver &amp;quot;intel&amp;quot;&lt;br /&gt;
   Option &amp;quot;AccelMethod&amp;quot; &amp;quot;uxa&amp;quot;&lt;br /&gt;
 EndSection&lt;br /&gt;
&lt;br /&gt;
This seems to resolve video playback issues. What happens is that the video will not play, though audio will. Only the first frame or so is visible. Video seems to be unable to display. This is a documented fix. The important part is AccelMethod.&lt;br /&gt;
https://wiki.archlinux.org/index.php/Intel_Graphics&lt;br /&gt;
Also documented in forums that I can't seem to find at the moment.&lt;br /&gt;
&lt;br /&gt;
===Python3 Script Won't Run===&lt;br /&gt;
 $ ztdl&lt;br /&gt;
 env: can't execute python&lt;br /&gt;
solution:&lt;br /&gt;
 python3 /usr/local/bin/ztdl&lt;br /&gt;
&lt;br /&gt;
===Cloning HDD===&lt;br /&gt;
&lt;br /&gt;
When cloning a hdd, do the&lt;br /&gt;
following:&lt;br /&gt;
*clonezilla or otherwise rsync partitions and recreate partitions to similar boundaries&lt;br /&gt;
by default clonezilla might fail, due to -C not being set. There is an icds option for restore, but it can either be edited into /usr/sbin/ocs-onthefly  for partclone or just rsync then:&lt;br /&gt;
*edit etc fstab  uuids&lt;br /&gt;
*edit (boot partition) grub/grub.cfg root=uuid=whatever to root=/dev/sda3&lt;br /&gt;
*can also be in /dev/sda1 - extlinux.conf&lt;br /&gt;
NOTE: normal editing of extlinux.conf can also be done with the extlinux in /etc/&lt;br /&gt;
&lt;br /&gt;
===Kernel, Initramfs recovery===&lt;br /&gt;
If upgrade fails halfway through for any reason (hdd failing, system in a broken state), you may be left with a unbootable machine. Keep an extra /boot/vmlinuz-lts and /boot/initramfs-lts and also a copy of that kernels /lib/modules/&amp;lt;kernelvers&amp;gt; around in case. I keep mine in a folder named /boot/recovery. Backup hdds help here. If you have a corrupt initramfs, or kernel, move the old files back over to /boot from another machine. Now, from the alpine machine (not from a different dist chroot, which didn't work for me btw), boot up, and run mkinitfs again. The command is easy to mess up, so here's the correct one (as of 3.12)&lt;br /&gt;
 mkinitfs -c /etc/mkinitfs/mkinitfs.conf -b / &amp;lt;kernelvers&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The kernel vers for the new kernel can be found from /lib/modules. It should also have a folder, as the script will load modules into the initramfs&lt;br /&gt;
ref:&lt;br /&gt;
https://wiki.alpinelinux.org/wiki/Running_Alpine_in_a_Docker_Container&lt;br /&gt;
&lt;br /&gt;
https://wiki.alpinelinux.org/wiki/NVME&lt;br /&gt;
&lt;br /&gt;
https://wiki.alpinelinux.org/wiki/Bootloaders&lt;br /&gt;
&lt;br /&gt;
https://wiki.alpinelinux.org/wiki/Setting_up_a_software_RAID_array&lt;br /&gt;
&lt;br /&gt;
===UTF-8 Characters===&lt;br /&gt;
If you see certain foreign language characters not showing up correctly, you can try installing different fonts.&lt;br /&gt;
 apk search ttf&lt;br /&gt;
But I found that changing in FF opensans to sans-serif fixed some of them for me. opensans had partial support for international characters.&lt;br /&gt;
&lt;br /&gt;
===History File Size===&lt;br /&gt;
Alpine uses ash, not bash. &lt;br /&gt;
 printenv&lt;br /&gt;
Histfilesize / histsize should be set correctly.&lt;br /&gt;
&lt;br /&gt;
===Search for package===&lt;br /&gt;
There's obv &lt;br /&gt;
 apk search &amp;lt;packagename&amp;gt; &lt;br /&gt;
but, there is also&lt;br /&gt;
 apk search -v --description 'something descriptive'&lt;br /&gt;
e.g.&lt;br /&gt;
 apk search -v --description 'browser'&lt;br /&gt;
&lt;br /&gt;
===Search for who owns a certain file===&lt;br /&gt;
 apk info -W ./somefile.so&lt;br /&gt;
Some info options (omitted a few):&amp;lt;pre&amp;gt;&lt;br /&gt;
Info options:&lt;br /&gt;
  -L, --contents          List contents of the PACKAGE&lt;br /&gt;
  -e, --installed         Check if PACKAGE is installed&lt;br /&gt;
  -W, --who-owns          Print the package owning the specified file&lt;br /&gt;
  -R, --depends           List packages that the PACKAGE depends on&lt;br /&gt;
  -r, --rdepends          List all packages depending on PACKAGE&lt;br /&gt;
  --replaces              List packages whom files PACKAGE might replace&lt;br /&gt;
  -w, --webpage           Show URL for more information about PACKAGE&lt;br /&gt;
  -s, --size              Show installed size of PACKAGE&lt;br /&gt;
  -d, --description       Print description for PACKAGE&lt;br /&gt;
  -a, --all               Print all information about PACKAGE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
===apk Update Between Versions===&lt;br /&gt;
* A couple releases are supported for a while. So even if a new one is out, the older one may still have updates.&lt;br /&gt;
* Follow directions on Wiki for upgrade. &lt;br /&gt;
* If you run out of space in boot (as I did) just back up or delete the old kernel and initramfs (they will be in a folder, e.g. 202012) then mkinitfs and grub-mkimage again. should boot.&lt;br /&gt;
* If you get errors on apk, there is an apk fix. This might also run mkinitfs and grub again.&lt;br /&gt;
&lt;br /&gt;
===Misc===&lt;br /&gt;
&lt;br /&gt;
 /etc/local.d&lt;br /&gt;
Allows for boot / shutdown scripts&lt;br /&gt;
&lt;br /&gt;
 /etc/apk/world&lt;br /&gt;
Lists all packages installed.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''text files''':&lt;br /&gt;
&lt;br /&gt;
Alpine uses a lot of text files for configuration. Text files are holy because they are accessible, editable, and in plain sight. DBs, hidden files, and registries are evil (when used for program flags/switches). Text files (in Alpine) are also minimal, and obvious where they are located. This makes editing / customization accessible to the novice user.&lt;br /&gt;
&lt;br /&gt;
==Links==&lt;br /&gt;
https://wiki.alpinelinux.org/wiki/Configure_Wake-on-LAN Configure_Wake-on-LAN&lt;br /&gt;
&lt;br /&gt;
gcompat - way to run glibc programs&lt;br /&gt;
&lt;br /&gt;
https://wiki.alpinelinux.org/wiki/Running_glibc_programs&lt;br /&gt;
&lt;br /&gt;
https://ariadne.space/2021/04/25/why-apk-tools-is-different-than-other-package-managers/&lt;br /&gt;
&lt;br /&gt;
https://wiki.alpinelinux.org/w/index.php?title=Mailing_lists&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{GNU\Linux}}&lt;/div&gt;</summary>
		<author><name>Adminguy</name></author>
	</entry>
	<entry>
		<id>http://steakwiki.com/index.php?title=Alpine&amp;diff=999</id>
		<title>Alpine</title>
		<link rel="alternate" type="text/html" href="http://steakwiki.com/index.php?title=Alpine&amp;diff=999"/>
		<updated>2021-05-24T04:55:34Z</updated>

		<summary type="html">&lt;p&gt;Adminguy: /* Search for who owns a certain file */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;small&amp;gt;&lt;br /&gt;
==General Tips==&lt;br /&gt;
===Building a package in Alpine===&lt;br /&gt;
&lt;br /&gt;
https://wiki.alpinelinux.org/wiki/Category_talk:Developer_Documentation#Building_from_source_and_creating_packages&lt;br /&gt;
&lt;br /&gt;
https://wiki.alpinelinux.org/wiki/Custom_Kernel&lt;br /&gt;
&lt;br /&gt;
===Xorg video playback stutters upon suspend / resume===&lt;br /&gt;
&lt;br /&gt;
I added the following configuration to xorg.conf&lt;br /&gt;
 Section &amp;quot;Device&amp;quot;&lt;br /&gt;
   Identifier &amp;quot;Intel Graphics&amp;quot;&lt;br /&gt;
   Driver &amp;quot;intel&amp;quot;&lt;br /&gt;
   Option &amp;quot;AccelMethod&amp;quot; &amp;quot;uxa&amp;quot;&lt;br /&gt;
 EndSection&lt;br /&gt;
&lt;br /&gt;
This seems to resolve video playback issues. What happens is that the video will not play, though audio will. Only the first frame or so is visible. Video seems to be unable to display. This is a documented fix. The important part is AccelMethod.&lt;br /&gt;
https://wiki.archlinux.org/index.php/Intel_Graphics&lt;br /&gt;
Also documented in forums that I can't seem to find at the moment.&lt;br /&gt;
&lt;br /&gt;
===Python3 Script Won't Run===&lt;br /&gt;
 $ ztdl&lt;br /&gt;
 env: can't execute python&lt;br /&gt;
solution:&lt;br /&gt;
 python3 /usr/local/bin/ztdl&lt;br /&gt;
&lt;br /&gt;
===Cloning HDD===&lt;br /&gt;
&lt;br /&gt;
When cloning a hdd, do the&lt;br /&gt;
following:&lt;br /&gt;
*clonezilla or otherwise rsync partitions and recreate partitions to similar boundaries&lt;br /&gt;
by default clonezilla might fail, due to -C not being set. There is an icds option for restore, but it can either be edited into /usr/sbin/ocs-onthefly  for partclone or just rsync then:&lt;br /&gt;
*edit etc fstab  uuids&lt;br /&gt;
*edit (boot partition) grub/grub.cfg root=uuid=whatever to root=/dev/sda3&lt;br /&gt;
*can also be in /dev/sda1 - extlinux.conf&lt;br /&gt;
NOTE: normal editing of extlinux.conf can also be done with the extlinux in /etc/&lt;br /&gt;
&lt;br /&gt;
===Kernel, Initramfs recovery===&lt;br /&gt;
If upgrade fails halfway through for any reason (hdd failing, system in a broken state), you may be left with a unbootable machine. Keep an extra /boot/vmlinuz-lts and /boot/initramfs-lts and also a copy of that kernels /lib/modules/&amp;lt;kernelvers&amp;gt; around in case. I keep mine in a folder named /boot/recovery. Backup hdds help here. If you have a corrupt initramfs, or kernel, move the old files back over to /boot from another machine. Now, from the alpine machine (not from a different dist chroot, which didn't work for me btw), boot up, and run mkinitfs again. The command is easy to mess up, so here's the correct one (as of 3.12)&lt;br /&gt;
 mkinitfs -c /etc/mkinitfs/mkinitfs.conf -b / &amp;lt;kernelvers&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The kernel vers for the new kernel can be found from /lib/modules. It should also have a folder, as the script will load modules into the initramfs&lt;br /&gt;
ref:&lt;br /&gt;
https://wiki.alpinelinux.org/wiki/Running_Alpine_in_a_Docker_Container&lt;br /&gt;
&lt;br /&gt;
https://wiki.alpinelinux.org/wiki/NVME&lt;br /&gt;
&lt;br /&gt;
https://wiki.alpinelinux.org/wiki/Bootloaders&lt;br /&gt;
&lt;br /&gt;
https://wiki.alpinelinux.org/wiki/Setting_up_a_software_RAID_array&lt;br /&gt;
&lt;br /&gt;
===UTF-8 Characters===&lt;br /&gt;
If you see certain foreign language characters not showing up correctly, you can try installing different fonts.&lt;br /&gt;
 apk search ttf&lt;br /&gt;
But I found that changing in FF opensans to sans-serif fixed some of them for me. opensans had partial support for international characters.&lt;br /&gt;
&lt;br /&gt;
===History File Size===&lt;br /&gt;
Alpine uses ash, not bash. &lt;br /&gt;
 printenv&lt;br /&gt;
Histfilesize / histsize should be set correctly.&lt;br /&gt;
&lt;br /&gt;
===Search for package===&lt;br /&gt;
There's obv &lt;br /&gt;
 apk search &amp;lt;packagename&amp;gt; &lt;br /&gt;
but, there is also&lt;br /&gt;
 apk search -v --description 'something descriptive'&lt;br /&gt;
e.g.&lt;br /&gt;
 apk search -v --description 'browser'&lt;br /&gt;
&lt;br /&gt;
===Search for who owns a certain file===&lt;br /&gt;
 apk info -W ./somefile.so&lt;br /&gt;
Some info options (omitted a few):&amp;lt;pre&amp;gt;&lt;br /&gt;
Info options:&lt;br /&gt;
  -L, --contents          List contents of the PACKAGE&lt;br /&gt;
  -e, --installed         Check if PACKAGE is installed&lt;br /&gt;
  -W, --who-owns          Print the package owning the specified file&lt;br /&gt;
  -R, --depends           List packages that the PACKAGE depends on&lt;br /&gt;
  -r, --rdepends          List all packages depending on PACKAGE&lt;br /&gt;
  --replaces              List packages whom files PACKAGE might replace&lt;br /&gt;
  -w, --webpage           Show URL for more information about PACKAGE&lt;br /&gt;
  -s, --size              Show installed size of PACKAGE&lt;br /&gt;
  -d, --description       Print description for PACKAGE&lt;br /&gt;
  -a, --all               Print all information about PACKAGE&lt;br /&gt;
&lt;br /&gt;
===apk Update Between Versions===&lt;br /&gt;
* Follow directions on Wiki for upgrade. &lt;br /&gt;
* If you run out of space in boot (as I did) just back up or delete the old kernel and initramfs (they will be in a folder, e.g. 202012) then mkinitfs and grub-mkimage again. should boot.&lt;br /&gt;
* If you get errors on apk, there is an apk fix. This might also run mkinitfs and grub again.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Misc===&lt;br /&gt;
&lt;br /&gt;
 /etc/local.d&lt;br /&gt;
Allows for boot / shutdown scripts&lt;br /&gt;
&lt;br /&gt;
 /etc/apk/world&lt;br /&gt;
Lists all packages installed.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''text files''':&lt;br /&gt;
&lt;br /&gt;
Alpine uses a lot of text files for configuration. Text files are holy because they are accessible, editable, and in plain sight. DBs, hidden files, and registries are evil (when used for program flags/switches). Text files (in Alpine) are also minimal, and obvious where they are located. This makes editing / customization accessible to the novice user.&lt;br /&gt;
&lt;br /&gt;
==Links==&lt;br /&gt;
https://wiki.alpinelinux.org/wiki/Configure_Wake-on-LAN Configure_Wake-on-LAN&lt;br /&gt;
&lt;br /&gt;
gcompat - way to run glibc programs&lt;br /&gt;
&lt;br /&gt;
https://wiki.alpinelinux.org/wiki/Running_glibc_programs&lt;br /&gt;
&lt;br /&gt;
https://ariadne.space/2021/04/25/why-apk-tools-is-different-than-other-package-managers/&lt;br /&gt;
&lt;br /&gt;
https://wiki.alpinelinux.org/w/index.php?title=Mailing_lists&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{GNU\Linux}}&lt;/div&gt;</summary>
		<author><name>Adminguy</name></author>
	</entry>
	<entry>
		<id>http://steakwiki.com/index.php?title=Alpine&amp;diff=998</id>
		<title>Alpine</title>
		<link rel="alternate" type="text/html" href="http://steakwiki.com/index.php?title=Alpine&amp;diff=998"/>
		<updated>2021-05-06T05:14:12Z</updated>

		<summary type="html">&lt;p&gt;Adminguy: /* Misc */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;small&amp;gt;&lt;br /&gt;
==General Tips==&lt;br /&gt;
===Building a package in Alpine===&lt;br /&gt;
&lt;br /&gt;
https://wiki.alpinelinux.org/wiki/Category_talk:Developer_Documentation#Building_from_source_and_creating_packages&lt;br /&gt;
&lt;br /&gt;
https://wiki.alpinelinux.org/wiki/Custom_Kernel&lt;br /&gt;
&lt;br /&gt;
===Xorg video playback stutters upon suspend / resume===&lt;br /&gt;
&lt;br /&gt;
I added the following configuration to xorg.conf&lt;br /&gt;
 Section &amp;quot;Device&amp;quot;&lt;br /&gt;
   Identifier &amp;quot;Intel Graphics&amp;quot;&lt;br /&gt;
   Driver &amp;quot;intel&amp;quot;&lt;br /&gt;
   Option &amp;quot;AccelMethod&amp;quot; &amp;quot;uxa&amp;quot;&lt;br /&gt;
 EndSection&lt;br /&gt;
&lt;br /&gt;
This seems to resolve video playback issues. What happens is that the video will not play, though audio will. Only the first frame or so is visible. Video seems to be unable to display. This is a documented fix. The important part is AccelMethod.&lt;br /&gt;
https://wiki.archlinux.org/index.php/Intel_Graphics&lt;br /&gt;
Also documented in forums that I can't seem to find at the moment.&lt;br /&gt;
&lt;br /&gt;
===Python3 Script Won't Run===&lt;br /&gt;
 $ ztdl&lt;br /&gt;
 env: can't execute python&lt;br /&gt;
solution:&lt;br /&gt;
 python3 /usr/local/bin/ztdl&lt;br /&gt;
&lt;br /&gt;
===Cloning HDD===&lt;br /&gt;
&lt;br /&gt;
When cloning a hdd, do the&lt;br /&gt;
following:&lt;br /&gt;
*clonezilla or otherwise rsync partitions and recreate partitions to similar boundaries&lt;br /&gt;
by default clonezilla might fail, due to -C not being set. There is an icds option for restore, but it can either be edited into /usr/sbin/ocs-onthefly  for partclone or just rsync then:&lt;br /&gt;
*edit etc fstab  uuids&lt;br /&gt;
*edit (boot partition) grub/grub.cfg root=uuid=whatever to root=/dev/sda3&lt;br /&gt;
*can also be in /dev/sda1 - extlinux.conf&lt;br /&gt;
NOTE: normal editing of extlinux.conf can also be done with the extlinux in /etc/&lt;br /&gt;
&lt;br /&gt;
===Kernel, Initramfs recovery===&lt;br /&gt;
If upgrade fails halfway through for any reason (hdd failing, system in a broken state), you may be left with a unbootable machine. Keep an extra /boot/vmlinuz-lts and /boot/initramfs-lts and also a copy of that kernels /lib/modules/&amp;lt;kernelvers&amp;gt; around in case. I keep mine in a folder named /boot/recovery. Backup hdds help here. If you have a corrupt initramfs, or kernel, move the old files back over to /boot from another machine. Now, from the alpine machine (not from a different dist chroot, which didn't work for me btw), boot up, and run mkinitfs again. The command is easy to mess up, so here's the correct one (as of 3.12)&lt;br /&gt;
 mkinitfs -c /etc/mkinitfs/mkinitfs.conf -b / &amp;lt;kernelvers&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The kernel vers for the new kernel can be found from /lib/modules. It should also have a folder, as the script will load modules into the initramfs&lt;br /&gt;
ref:&lt;br /&gt;
https://wiki.alpinelinux.org/wiki/Running_Alpine_in_a_Docker_Container&lt;br /&gt;
&lt;br /&gt;
https://wiki.alpinelinux.org/wiki/NVME&lt;br /&gt;
&lt;br /&gt;
https://wiki.alpinelinux.org/wiki/Bootloaders&lt;br /&gt;
&lt;br /&gt;
https://wiki.alpinelinux.org/wiki/Setting_up_a_software_RAID_array&lt;br /&gt;
&lt;br /&gt;
===UTF-8 Characters===&lt;br /&gt;
If you see certain foreign language characters not showing up correctly, you can try installing different fonts.&lt;br /&gt;
 apk search ttf&lt;br /&gt;
But I found that changing in FF opensans to sans-serif fixed some of them for me. opensans had partial support for international characters.&lt;br /&gt;
&lt;br /&gt;
===History File Size===&lt;br /&gt;
Alpine uses ash, not bash. &lt;br /&gt;
 printenv&lt;br /&gt;
Histfilesize / histsize should be set correctly.&lt;br /&gt;
&lt;br /&gt;
===Search for package===&lt;br /&gt;
There's obv &lt;br /&gt;
 apk search &amp;lt;packagename&amp;gt; &lt;br /&gt;
but, there is also&lt;br /&gt;
 apk search -v --description 'something descriptive'&lt;br /&gt;
e.g.&lt;br /&gt;
 apk search -v --description 'browser'&lt;br /&gt;
&lt;br /&gt;
===Search for who owns a certain file===&lt;br /&gt;
 apk info -W ./somefile.so&lt;br /&gt;
Some info options (omitted a few):&amp;lt;pre&amp;gt;&lt;br /&gt;
Info options:&lt;br /&gt;
  -L, --contents          List contents of the PACKAGE&lt;br /&gt;
  -e, --installed         Check if PACKAGE is installed&lt;br /&gt;
  -W, --who-owns          Print the package owning the specified file&lt;br /&gt;
  -R, --depends           List packages that the PACKAGE depends on&lt;br /&gt;
  -r, --rdepends          List all packages depending on PACKAGE&lt;br /&gt;
  --replaces              List packages whom files PACKAGE might replace&lt;br /&gt;
  -w, --webpage           Show URL for more information about PACKAGE&lt;br /&gt;
  -s, --size              Show installed size of PACKAGE&lt;br /&gt;
  -d, --description       Print description for PACKAGE&lt;br /&gt;
  -a, --all               Print all information about PACKAGE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Misc===&lt;br /&gt;
&lt;br /&gt;
 /etc/local.d&lt;br /&gt;
Allows for boot / shutdown scripts&lt;br /&gt;
&lt;br /&gt;
 /etc/apk/world&lt;br /&gt;
Lists all packages installed.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''text files''':&lt;br /&gt;
&lt;br /&gt;
Alpine uses a lot of text files for configuration. Text files are holy because they are accessible, editable, and in plain sight. DBs, hidden files, and registries are evil (when used for program flags/switches). Text files (in Alpine) are also minimal, and obvious where they are located. This makes editing / customization accessible to the novice user.&lt;br /&gt;
&lt;br /&gt;
==Links==&lt;br /&gt;
https://wiki.alpinelinux.org/wiki/Configure_Wake-on-LAN Configure_Wake-on-LAN&lt;br /&gt;
&lt;br /&gt;
gcompat - way to run glibc programs&lt;br /&gt;
&lt;br /&gt;
https://wiki.alpinelinux.org/wiki/Running_glibc_programs&lt;br /&gt;
&lt;br /&gt;
https://ariadne.space/2021/04/25/why-apk-tools-is-different-than-other-package-managers/&lt;br /&gt;
&lt;br /&gt;
https://wiki.alpinelinux.org/w/index.php?title=Mailing_lists&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{GNU\Linux}}&lt;/div&gt;</summary>
		<author><name>Adminguy</name></author>
	</entry>
	<entry>
		<id>http://steakwiki.com/index.php?title=Alpine&amp;diff=997</id>
		<title>Alpine</title>
		<link rel="alternate" type="text/html" href="http://steakwiki.com/index.php?title=Alpine&amp;diff=997"/>
		<updated>2021-05-06T05:13:09Z</updated>

		<summary type="html">&lt;p&gt;Adminguy: /* Search for who owns a certain file */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;small&amp;gt;&lt;br /&gt;
==General Tips==&lt;br /&gt;
===Building a package in Alpine===&lt;br /&gt;
&lt;br /&gt;
https://wiki.alpinelinux.org/wiki/Category_talk:Developer_Documentation#Building_from_source_and_creating_packages&lt;br /&gt;
&lt;br /&gt;
https://wiki.alpinelinux.org/wiki/Custom_Kernel&lt;br /&gt;
&lt;br /&gt;
===Xorg video playback stutters upon suspend / resume===&lt;br /&gt;
&lt;br /&gt;
I added the following configuration to xorg.conf&lt;br /&gt;
 Section &amp;quot;Device&amp;quot;&lt;br /&gt;
   Identifier &amp;quot;Intel Graphics&amp;quot;&lt;br /&gt;
   Driver &amp;quot;intel&amp;quot;&lt;br /&gt;
   Option &amp;quot;AccelMethod&amp;quot; &amp;quot;uxa&amp;quot;&lt;br /&gt;
 EndSection&lt;br /&gt;
&lt;br /&gt;
This seems to resolve video playback issues. What happens is that the video will not play, though audio will. Only the first frame or so is visible. Video seems to be unable to display. This is a documented fix. The important part is AccelMethod.&lt;br /&gt;
https://wiki.archlinux.org/index.php/Intel_Graphics&lt;br /&gt;
Also documented in forums that I can't seem to find at the moment.&lt;br /&gt;
&lt;br /&gt;
===Python3 Script Won't Run===&lt;br /&gt;
 $ ztdl&lt;br /&gt;
 env: can't execute python&lt;br /&gt;
solution:&lt;br /&gt;
 python3 /usr/local/bin/ztdl&lt;br /&gt;
&lt;br /&gt;
===Cloning HDD===&lt;br /&gt;
&lt;br /&gt;
When cloning a hdd, do the&lt;br /&gt;
following:&lt;br /&gt;
*clonezilla or otherwise rsync partitions and recreate partitions to similar boundaries&lt;br /&gt;
by default clonezilla might fail, due to -C not being set. There is an icds option for restore, but it can either be edited into /usr/sbin/ocs-onthefly  for partclone or just rsync then:&lt;br /&gt;
*edit etc fstab  uuids&lt;br /&gt;
*edit (boot partition) grub/grub.cfg root=uuid=whatever to root=/dev/sda3&lt;br /&gt;
*can also be in /dev/sda1 - extlinux.conf&lt;br /&gt;
NOTE: normal editing of extlinux.conf can also be done with the extlinux in /etc/&lt;br /&gt;
&lt;br /&gt;
===Kernel, Initramfs recovery===&lt;br /&gt;
If upgrade fails halfway through for any reason (hdd failing, system in a broken state), you may be left with a unbootable machine. Keep an extra /boot/vmlinuz-lts and /boot/initramfs-lts and also a copy of that kernels /lib/modules/&amp;lt;kernelvers&amp;gt; around in case. I keep mine in a folder named /boot/recovery. Backup hdds help here. If you have a corrupt initramfs, or kernel, move the old files back over to /boot from another machine. Now, from the alpine machine (not from a different dist chroot, which didn't work for me btw), boot up, and run mkinitfs again. The command is easy to mess up, so here's the correct one (as of 3.12)&lt;br /&gt;
 mkinitfs -c /etc/mkinitfs/mkinitfs.conf -b / &amp;lt;kernelvers&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The kernel vers for the new kernel can be found from /lib/modules. It should also have a folder, as the script will load modules into the initramfs&lt;br /&gt;
ref:&lt;br /&gt;
https://wiki.alpinelinux.org/wiki/Running_Alpine_in_a_Docker_Container&lt;br /&gt;
&lt;br /&gt;
https://wiki.alpinelinux.org/wiki/NVME&lt;br /&gt;
&lt;br /&gt;
https://wiki.alpinelinux.org/wiki/Bootloaders&lt;br /&gt;
&lt;br /&gt;
https://wiki.alpinelinux.org/wiki/Setting_up_a_software_RAID_array&lt;br /&gt;
&lt;br /&gt;
===UTF-8 Characters===&lt;br /&gt;
If you see certain foreign language characters not showing up correctly, you can try installing different fonts.&lt;br /&gt;
 apk search ttf&lt;br /&gt;
But I found that changing in FF opensans to sans-serif fixed some of them for me. opensans had partial support for international characters.&lt;br /&gt;
&lt;br /&gt;
===History File Size===&lt;br /&gt;
Alpine uses ash, not bash. &lt;br /&gt;
 printenv&lt;br /&gt;
Histfilesize / histsize should be set correctly.&lt;br /&gt;
&lt;br /&gt;
===Search for package===&lt;br /&gt;
There's obv &lt;br /&gt;
 apk search &amp;lt;packagename&amp;gt; &lt;br /&gt;
but, there is also&lt;br /&gt;
 apk search -v --description 'something descriptive'&lt;br /&gt;
e.g.&lt;br /&gt;
 apk search -v --description 'browser'&lt;br /&gt;
&lt;br /&gt;
===Search for who owns a certain file===&lt;br /&gt;
 apk info -W ./somefile.so&lt;br /&gt;
Some info options (omitted a few):&amp;lt;pre&amp;gt;&lt;br /&gt;
Info options:&lt;br /&gt;
  -L, --contents          List contents of the PACKAGE&lt;br /&gt;
  -e, --installed         Check if PACKAGE is installed&lt;br /&gt;
  -W, --who-owns          Print the package owning the specified file&lt;br /&gt;
  -R, --depends           List packages that the PACKAGE depends on&lt;br /&gt;
  -r, --rdepends          List all packages depending on PACKAGE&lt;br /&gt;
  --replaces              List packages whom files PACKAGE might replace&lt;br /&gt;
  -w, --webpage           Show URL for more information about PACKAGE&lt;br /&gt;
  -s, --size              Show installed size of PACKAGE&lt;br /&gt;
  -d, --description       Print description for PACKAGE&lt;br /&gt;
  -a, --all               Print all information about PACKAGE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Misc===&lt;br /&gt;
&lt;br /&gt;
 /etc/local.d&lt;br /&gt;
Allows for boot / shutdown scripts&lt;br /&gt;
&lt;br /&gt;
 /etc/apk/world&lt;br /&gt;
Lists all packages installed.&lt;br /&gt;
&lt;br /&gt;
Alpine uses a lot of text files for configuration. Text files are holy because they are accessible, editable, and in plain sight. DBs, hidden files, and registries are evil (when used for program flags/switches). Text files are also minimal, and obvious where they are located. This makes editing / customization accessible to the novice user.&lt;br /&gt;
&lt;br /&gt;
==Links==&lt;br /&gt;
https://wiki.alpinelinux.org/wiki/Configure_Wake-on-LAN Configure_Wake-on-LAN&lt;br /&gt;
&lt;br /&gt;
gcompat - way to run glibc programs&lt;br /&gt;
&lt;br /&gt;
https://wiki.alpinelinux.org/wiki/Running_glibc_programs&lt;br /&gt;
&lt;br /&gt;
https://ariadne.space/2021/04/25/why-apk-tools-is-different-than-other-package-managers/&lt;br /&gt;
&lt;br /&gt;
https://wiki.alpinelinux.org/w/index.php?title=Mailing_lists&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{GNU\Linux}}&lt;/div&gt;</summary>
		<author><name>Adminguy</name></author>
	</entry>
	<entry>
		<id>http://steakwiki.com/index.php?title=Alpine&amp;diff=996</id>
		<title>Alpine</title>
		<link rel="alternate" type="text/html" href="http://steakwiki.com/index.php?title=Alpine&amp;diff=996"/>
		<updated>2021-05-06T05:09:47Z</updated>

		<summary type="html">&lt;p&gt;Adminguy: /* Links */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;small&amp;gt;&lt;br /&gt;
==General Tips==&lt;br /&gt;
===Building a package in Alpine===&lt;br /&gt;
&lt;br /&gt;
https://wiki.alpinelinux.org/wiki/Category_talk:Developer_Documentation#Building_from_source_and_creating_packages&lt;br /&gt;
&lt;br /&gt;
https://wiki.alpinelinux.org/wiki/Custom_Kernel&lt;br /&gt;
&lt;br /&gt;
===Xorg video playback stutters upon suspend / resume===&lt;br /&gt;
&lt;br /&gt;
I added the following configuration to xorg.conf&lt;br /&gt;
 Section &amp;quot;Device&amp;quot;&lt;br /&gt;
   Identifier &amp;quot;Intel Graphics&amp;quot;&lt;br /&gt;
   Driver &amp;quot;intel&amp;quot;&lt;br /&gt;
   Option &amp;quot;AccelMethod&amp;quot; &amp;quot;uxa&amp;quot;&lt;br /&gt;
 EndSection&lt;br /&gt;
&lt;br /&gt;
This seems to resolve video playback issues. What happens is that the video will not play, though audio will. Only the first frame or so is visible. Video seems to be unable to display. This is a documented fix. The important part is AccelMethod.&lt;br /&gt;
https://wiki.archlinux.org/index.php/Intel_Graphics&lt;br /&gt;
Also documented in forums that I can't seem to find at the moment.&lt;br /&gt;
&lt;br /&gt;
===Python3 Script Won't Run===&lt;br /&gt;
 $ ztdl&lt;br /&gt;
 env: can't execute python&lt;br /&gt;
solution:&lt;br /&gt;
 python3 /usr/local/bin/ztdl&lt;br /&gt;
&lt;br /&gt;
===Cloning HDD===&lt;br /&gt;
&lt;br /&gt;
When cloning a hdd, do the&lt;br /&gt;
following:&lt;br /&gt;
*clonezilla or otherwise rsync partitions and recreate partitions to similar boundaries&lt;br /&gt;
by default clonezilla might fail, due to -C not being set. There is an icds option for restore, but it can either be edited into /usr/sbin/ocs-onthefly  for partclone or just rsync then:&lt;br /&gt;
*edit etc fstab  uuids&lt;br /&gt;
*edit (boot partition) grub/grub.cfg root=uuid=whatever to root=/dev/sda3&lt;br /&gt;
*can also be in /dev/sda1 - extlinux.conf&lt;br /&gt;
NOTE: normal editing of extlinux.conf can also be done with the extlinux in /etc/&lt;br /&gt;
&lt;br /&gt;
===Kernel, Initramfs recovery===&lt;br /&gt;
If upgrade fails halfway through for any reason (hdd failing, system in a broken state), you may be left with a unbootable machine. Keep an extra /boot/vmlinuz-lts and /boot/initramfs-lts and also a copy of that kernels /lib/modules/&amp;lt;kernelvers&amp;gt; around in case. I keep mine in a folder named /boot/recovery. Backup hdds help here. If you have a corrupt initramfs, or kernel, move the old files back over to /boot from another machine. Now, from the alpine machine (not from a different dist chroot, which didn't work for me btw), boot up, and run mkinitfs again. The command is easy to mess up, so here's the correct one (as of 3.12)&lt;br /&gt;
 mkinitfs -c /etc/mkinitfs/mkinitfs.conf -b / &amp;lt;kernelvers&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The kernel vers for the new kernel can be found from /lib/modules. It should also have a folder, as the script will load modules into the initramfs&lt;br /&gt;
ref:&lt;br /&gt;
https://wiki.alpinelinux.org/wiki/Running_Alpine_in_a_Docker_Container&lt;br /&gt;
&lt;br /&gt;
https://wiki.alpinelinux.org/wiki/NVME&lt;br /&gt;
&lt;br /&gt;
https://wiki.alpinelinux.org/wiki/Bootloaders&lt;br /&gt;
&lt;br /&gt;
https://wiki.alpinelinux.org/wiki/Setting_up_a_software_RAID_array&lt;br /&gt;
&lt;br /&gt;
===UTF-8 Characters===&lt;br /&gt;
If you see certain foreign language characters not showing up correctly, you can try installing different fonts.&lt;br /&gt;
 apk search ttf&lt;br /&gt;
But I found that changing in FF opensans to sans-serif fixed some of them for me. opensans had partial support for international characters.&lt;br /&gt;
&lt;br /&gt;
===History File Size===&lt;br /&gt;
Alpine uses ash, not bash. &lt;br /&gt;
 printenv&lt;br /&gt;
Histfilesize / histsize should be set correctly.&lt;br /&gt;
&lt;br /&gt;
===Search for package===&lt;br /&gt;
There's obv &lt;br /&gt;
 apk search &amp;lt;packagename&amp;gt; &lt;br /&gt;
but, there is also&lt;br /&gt;
 apk search -v --description 'something descriptive'&lt;br /&gt;
e.g.&lt;br /&gt;
 apk search -v --description 'browser'&lt;br /&gt;
&lt;br /&gt;
===Search for who owns a certain file===&lt;br /&gt;
 apk info -W ./somefile.so&lt;br /&gt;
Some info options (omitted a few):&amp;lt;pre&amp;gt;&lt;br /&gt;
Info options:&lt;br /&gt;
  -L, --contents          List contents of the PACKAGE&lt;br /&gt;
  -e, --installed         Check if PACKAGE is installed&lt;br /&gt;
  -W, --who-owns          Print the package owning the specified file&lt;br /&gt;
  -R, --depends           List packages that the PACKAGE depends on&lt;br /&gt;
  -r, --rdepends          List all packages depending on PACKAGE&lt;br /&gt;
  --replaces              List packages whom files PACKAGE might replace&lt;br /&gt;
  -w, --webpage           Show URL for more information about PACKAGE&lt;br /&gt;
  -s, --size              Show installed size of PACKAGE&lt;br /&gt;
  -d, --description       Print description for PACKAGE&lt;br /&gt;
  -a, --all               Print all information about PACKAGE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Links==&lt;br /&gt;
https://wiki.alpinelinux.org/wiki/Configure_Wake-on-LAN Configure_Wake-on-LAN&lt;br /&gt;
&lt;br /&gt;
gcompat - way to run glibc programs&lt;br /&gt;
&lt;br /&gt;
https://wiki.alpinelinux.org/wiki/Running_glibc_programs&lt;br /&gt;
&lt;br /&gt;
https://ariadne.space/2021/04/25/why-apk-tools-is-different-than-other-package-managers/&lt;br /&gt;
&lt;br /&gt;
https://wiki.alpinelinux.org/w/index.php?title=Mailing_lists&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{GNU\Linux}}&lt;/div&gt;</summary>
		<author><name>Adminguy</name></author>
	</entry>
	<entry>
		<id>http://steakwiki.com/index.php?title=Openwrt&amp;diff=995</id>
		<title>Openwrt</title>
		<link rel="alternate" type="text/html" href="http://steakwiki.com/index.php?title=Openwrt&amp;diff=995"/>
		<updated>2021-05-04T18:23:20Z</updated>

		<summary type="html">&lt;p&gt;Adminguy: /* misc */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;small&amp;gt;&lt;br /&gt;
==Recommended Router==&lt;br /&gt;
Current: &lt;br /&gt;
&lt;br /&gt;
high traffic: x86 PC&lt;br /&gt;
&lt;br /&gt;
low traffic: ARM / MIPS with the following:&lt;br /&gt;
 * uboot bootloader&lt;br /&gt;
 * doesn't require multiple hoops to install (i.e. no 'two different' serial speeds on the same UART. moron ubiquiti...)&lt;br /&gt;
 * promotes FOSS and is ok with LEDE/openwrt&lt;br /&gt;
&lt;br /&gt;
Still evaluating them, but it looks like gl.inet is the way to go.&lt;br /&gt;
&lt;br /&gt;
OLD:&lt;br /&gt;
* https://openwrt.org/toh/mikrotik/rb2011&lt;br /&gt;
&lt;br /&gt;
I used to use these as they are rack mount, but the bootloader is proprietary and i had two of them brick themselves for no reason during the 2nd sysupgrade. Proprietary software. Not Even Once.&lt;br /&gt;
&lt;br /&gt;
High-end companies can look at https://www.opencompute.org/products&lt;br /&gt;
&lt;br /&gt;
===Recommended wireless AP===&lt;br /&gt;
Open mesh in Oregon was good. But they were bought out. They are now doomed. China has gl.inet which is basically the same as open mesh, although they specialize in small travel routers. Only buy wifi APs that support openwrt.&lt;br /&gt;
&lt;br /&gt;
==Tips==&lt;br /&gt;
&lt;br /&gt;
===port forwarding===&lt;br /&gt;
Port forwarding is two steps:&lt;br /&gt;
# redirect port from outside to internal (NAT)&lt;br /&gt;
# allow access from outside to inside via this port (firewall)&lt;br /&gt;
&lt;br /&gt;
{{cat|/etc/config/firewall|config redirect&lt;br /&gt;
        option name 'PassthroughformyServer'&lt;br /&gt;
        option src 'wan'&lt;br /&gt;
        option proto 'tcp'&lt;br /&gt;
        option src_dport '80'&lt;br /&gt;
        option dest_ip '192.168.1.100'&lt;br /&gt;
        option dest_port '80'&lt;br /&gt;
        option target 'DNAT'&lt;br /&gt;
        option dest 'lan'&lt;br /&gt;
&lt;br /&gt;
config rule&lt;br /&gt;
        option src 'wan'&lt;br /&gt;
        option proto 'tcp'&lt;br /&gt;
        option dest_port '80'&lt;br /&gt;
        option target 'ACCEPT'&lt;br /&gt;
&lt;br /&gt;
}}&lt;br /&gt;
Note: Proto can be 'tcp' OR 'tcpudp' OR 'udp'&lt;br /&gt;
&lt;br /&gt;
===reserved ip / static lease===&lt;br /&gt;
{{cat|/etc/config/dhcp|config host&lt;br /&gt;
        option ip 192.168.1.122&lt;br /&gt;
        option mac c2:44:32:18:cd:ab&lt;br /&gt;
        option name reservedipcomputer}}&lt;br /&gt;
ref: https://openwrt.org/docs/guide-user/base-system/dhcp_configuration#static_leases&lt;br /&gt;
&lt;br /&gt;
I tried to add this to the wiki, but someone (https://openwrt.org/docs/guide-user/base-system/dhcp_configuration?rev=1596434574) decided to replace my simple solution with an obfuscated one that requires uci commands. So instead, it will remain here.&lt;br /&gt;
EDIT: I added it back. See how long that lasts...&lt;br /&gt;
&lt;br /&gt;
===openvpn===&lt;br /&gt;
&amp;lt;code&amp;gt;opkg install openvpn-openssl&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{cat|/etc/config/openvpn| config openvpn 'custom_config'&lt;br /&gt;
        option config '/etc/openvpn/myconfigfile.ovpn'&lt;br /&gt;
}}&lt;br /&gt;
And your .ovpn in /etc/openvpn/.&lt;br /&gt;
&lt;br /&gt;
===aliases===&lt;br /&gt;
Put in /etc/profile. e.g.&lt;br /&gt;
&amp;lt;pre&amp;gt;export TERM=xterm&lt;br /&gt;
alias vpnme= 'openvpn --config /etc/openvpn/myconfigfile.ovpn &amp;amp; ./script.sh &amp;amp;'&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===mwan3===&lt;br /&gt;
&lt;br /&gt;
Mwan3 can be tricky. The wiki lacks a quick start*. The following files get edited:&lt;br /&gt;
 /etc/config/network&lt;br /&gt;
 /etc/config/mwan3&lt;br /&gt;
 /etc/config/firewall&lt;br /&gt;
&lt;br /&gt;
Tips Page: [[Mwan3_On_Openwrt]]&lt;br /&gt;
&lt;br /&gt;
If you add a new WAN interface, (e.g. wanb or wan2) you must add wanb to the existing wan firewall zone for outgoing comms. How this is handled differs from 17 to 19.*2&lt;br /&gt;
&lt;br /&gt;
Balanced policies can have issues with connections jumping from one wan to another.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;small&amp;gt;* the current mwan3 page is a lengthy multi-page behemoth (which has grown over time) that expects no less of you than to understand all functional and architectural details of how the failover works.  It's a lot for someone that just wants to setup backup internet. But mwan3 can and does work.&lt;br /&gt;
*2 ctrl-f for firewall comes up with half a dozen mentions of firewall masking (something done automatically) and one easily missable note, for GUI setup only, about adding the new wan2 to the firewall zone. An absolutely required step.&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===iptables vs fw3===&lt;br /&gt;
In the firewall:&lt;br /&gt;
 iptables -L &lt;br /&gt;
will list current rules, but the iptables rule generator is fw3.&lt;br /&gt;
 fw3 print&lt;br /&gt;
Will display iptables commands that make up the firewall. fw3 script is described in firewall pages on official wiki. Please review that.&lt;br /&gt;
&lt;br /&gt;
===less with / search===&lt;br /&gt;
The stock 'less' command does not include '/' search. &lt;br /&gt;
 opkg install less&lt;br /&gt;
To get forward slash search&lt;br /&gt;
https://dev.archive.openwrt.org/ticket/7132&lt;br /&gt;
&lt;br /&gt;
===remove poweroff command===&lt;br /&gt;
 cd /sbin/&lt;br /&gt;
 rm ./poweroff&lt;br /&gt;
Now to power off, you must type &lt;br /&gt;
 busybox poweroff&lt;br /&gt;
This will keep you from accidentally shutting down a router.&lt;br /&gt;
&lt;br /&gt;
===misc===&lt;br /&gt;
start wifi&lt;br /&gt;
 wifi up  &lt;br /&gt;
 wifi status&lt;br /&gt;
&lt;br /&gt;
transfer files using nc / scp on lean embedded devices&lt;br /&gt;
&lt;br /&gt;
===Logging===&lt;br /&gt;
&lt;br /&gt;
display (RAM based) logs (note that this is not in /var/log/messages...)&lt;br /&gt;
 logread&lt;br /&gt;
https://openwrt.org/docs/guide-user/perf_and_log/start&lt;br /&gt;
e.g.&lt;br /&gt;
https://openwrt.org/docs/guide-user/perf_and_log/statistic.custom&lt;br /&gt;
and&lt;br /&gt;
https://openwrt.org/docs/guide-user/perf_and_log/log.messages&lt;br /&gt;
&lt;br /&gt;
===Blink LEDs===&lt;br /&gt;
If you poke around the Linux Kernel you will come across core Netfilter configuration. It's&lt;br /&gt;
not in an obvious place, but in 5.4 here:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Location:                                                                                                                            │&lt;br /&gt;
  │     -&amp;gt; Networking support (NET [=y])                                                                                                   │&lt;br /&gt;
  │       -&amp;gt; Networking options                                                                                                            │&lt;br /&gt;
  │         -&amp;gt; Network packet filtering framework (Netfilter) (NETFILTER [=y])                                                             │&lt;br /&gt;
  │           -&amp;gt; Core Netfilter Configuration                                                                                              │&lt;br /&gt;
  │             -&amp;gt; Netfilter Xtables support (required for ip_tables) (NETFILTER_XTABLES [=y])&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Why am I poking around xtables support? Wireguard needs it for &amp;lt;5.6. But, in this page, you will find some familiar sights: REDIRECT,MASQUERADE,DROP,LOG, etc... All parameters for iptables. Here you will learn what the difference between REDIRECT and MASQUERADE is (one is input, one is output)(which is interesting, because it might be a thing people commonly get wrong, on online tips for using iptables, or if you don't know which does what, you won't know what to look for). Forget about that, there's one named LED. Hey that sounds interesting. That means I can control a LED from the firewall?&lt;br /&gt;
&lt;br /&gt;
Does this work with Openwrt? No idea, but from here I went to the official owrt docs&lt;br /&gt;
 https://openwrt.org/docs/guide-user/base-system/led_configuration&lt;br /&gt;
And you may already know the leds are there, but here's how to configure them. Some of them require modules. e.g.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
The LED flashes with link status and/or send and receive activity on the configured interface. If not installed already, install it with: &lt;br /&gt;
 opkg install kmod-ledtrig-netdev&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
will enable netdev, which will enable led activity on any NIC. so it requires that module and some configuration...&lt;br /&gt;
e.g.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#:/sys/devices/platform/leds/leds/:green:wan# ls&lt;br /&gt;
brightness      device_name     link            rx              trigger         uevent&lt;br /&gt;
device          interval        max_brightness  subsystem       tx&lt;br /&gt;
#:/sys/devices/platform/leds/leds/:green:wan# cat *&lt;br /&gt;
0&lt;br /&gt;
cat: read error: Is a directory&lt;br /&gt;
eth0.2&lt;br /&gt;
50&lt;br /&gt;
0&lt;br /&gt;
255&lt;br /&gt;
1&lt;br /&gt;
cat: read error: Is a directory&lt;br /&gt;
none switch0 timer default-on [netdev] phy0rx phy0tx phy0assoc phy0radio phy0tpt&lt;br /&gt;
0&lt;br /&gt;
OF_NAME=wan&lt;br /&gt;
OF_FULLNAME=/leds/wan&lt;br /&gt;
OF_COMPATIBLE_N=0&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
I had to set rx or tx to 1 (only 1 of them). and also needed to set device_name (not device like docs say) to eth0.2&lt;br /&gt;
&lt;br /&gt;
Just set a ping, then tweak the knobs; should start blinking.&lt;br /&gt;
&lt;br /&gt;
&amp;quot;But what if I want to blink more LEDs from userspace?&amp;quot; See [[Arduino]] for ulisp.&lt;br /&gt;
&lt;br /&gt;
===various links i found interesting===&lt;br /&gt;
&lt;br /&gt;
* https://openwrt.org/docs/guide-user/network/traffic-shaping/sqm - speed test, and traffic shaping to speed up a 'slow' network. protip: use x86 instead of arm if openwrt is slow.&lt;br /&gt;
&lt;br /&gt;
* https://openwrt.org/docs/guide-user/services/nas/netatalk_configuration - apple time machine backup server&lt;br /&gt;
&lt;br /&gt;
* https://openwrt.org/docs/guide-user/network/wan/multiwan/mwan3 - failover for wan. i have used this before, and it worked well.&lt;br /&gt;
&lt;br /&gt;
* https://openwrt.org/tag/faq - FAQs&lt;br /&gt;
&lt;br /&gt;
* https://openwrt.org/docs/techref/flash.layout - Partitions on &amp;lt;s&amp;gt;HDD&amp;lt;/s&amp;gt; flash. And overlay fs.&lt;br /&gt;
&lt;br /&gt;
* https://openwrt.org/docs/techref/start - Technical Reference. Has some informative dives into various aspects of low power routers. As an example see this link on flash: https://openwrt.org/docs/techref/flash IME, flash is built in obsolescence. usb drives, sd cards, and onboard flash tend to last much less than advertised. not recommended. SD and SSDs are a trap. from this: even 'reading' flash can cause bad blocks. that's right, even reading. therefore flash is guaranteed to fail. tech companies love it.&lt;br /&gt;
&lt;br /&gt;
* https://openwrt.org/docs/guide-developer/security&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{GNU\Linux}}&lt;/div&gt;</summary>
		<author><name>Adminguy</name></author>
	</entry>
	<entry>
		<id>http://steakwiki.com/index.php?title=Postgres&amp;diff=994</id>
		<title>Postgres</title>
		<link rel="alternate" type="text/html" href="http://steakwiki.com/index.php?title=Postgres&amp;diff=994"/>
		<updated>2021-04-15T21:20:51Z</updated>

		<summary type="html">&lt;p&gt;Adminguy: /* Usage */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Usage==&lt;br /&gt;
&lt;br /&gt;
Most commands are found by \?&lt;br /&gt;
e.g. &lt;br /&gt;
 \dt - list tables&lt;br /&gt;
 \l  - list databases&lt;br /&gt;
 \c  - connect to db&lt;br /&gt;
Since PostgreSQL 10, psql has \gx which is equal to mysql \G&lt;br /&gt;
 select * from sometable \gx&lt;br /&gt;
ref:stackex&lt;br /&gt;
&lt;br /&gt;
==Backup / Restore DB==&lt;br /&gt;
===backup===&lt;br /&gt;
This will run the dump as the postgres user via su, and avoids some of the permissions errors that can creep up.&lt;br /&gt;
 # cd /tmp&lt;br /&gt;
 (just need a writeable directory, aka 777)&lt;br /&gt;
 # su -c 'pg_dump mydb &amp;gt;&amp;gt; mydb_dump_2020.sql' postgres&lt;br /&gt;
assuming you have a postgres admin user, with all rights, this will backup the db. If you are remote, you might need something similar to (localhost/ip, ports, etc specified):&lt;br /&gt;
 pg_dump -U username -h localhost databasename &amp;gt;&amp;gt; sqlfile.sql&lt;br /&gt;
ref: https://stackoverflow.com/questions/37984733/postgresql-database-export-to-sql-file&lt;br /&gt;
===restore===&lt;br /&gt;
Create the new db:&lt;br /&gt;
 su - postgres&lt;br /&gt;
 psql&lt;br /&gt;
 create database bbbtest;&lt;br /&gt;
 grant all privileges on database bbbtest to mypguser;&lt;br /&gt;
 ALTER DATABASE bbbtest OWNER TO mypguser;&lt;br /&gt;
and postgres permissions are a disaster online for getting info on (unforunately, there is nothing like mysql's ''mysql -uroot -p -e &amp;quot;grant all on db.* to 'user'@localhost identified by 'pass';&amp;quot;''). But what does work is permissions for specific tables need to be enabled for the user, so:&lt;br /&gt;
 GRANT ALL ON sometableindb TO mypguser;&lt;br /&gt;
 \quit&lt;br /&gt;
 exit&lt;br /&gt;
Now, with that file&lt;br /&gt;
 # su -c 'psql -d newdbname --set ON_ERROR_STOP=on -f ./mydb_dump_2020.sql' postgres&lt;br /&gt;
&lt;br /&gt;
If you get errors, adjust data as needed or remove the ON_ERROR_STOP (some can be ignored,&lt;br /&gt;
some can not - use discretion). At least in some cases, you can move data without worrying about postgres versions. I executed a pg_dump from 11.# and imported to 9.6 without issue. Devuan Beowulf to Ascii.&lt;br /&gt;
&lt;br /&gt;
TIP: if you don't specify -d, then the data will get uploaded to one of the preexisting DB. Not good.&lt;br /&gt;
&lt;br /&gt;
Another approach:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
-- su - postgres&lt;br /&gt;
-- -- psql&lt;br /&gt;
-- -- -- create database bbbtest;&lt;br /&gt;
-- -- -- grant all privileges on database bbbtest to root;&lt;br /&gt;
-- -- -- \quit&lt;br /&gt;
-- -- exit&lt;br /&gt;
-- psql bbbtest &amp;lt; dbmake.sql&lt;br /&gt;
-- -- select * from A1;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Verify user permissions and upload was correct====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
su - mypguser&lt;br /&gt;
psql&lt;br /&gt;
select * from sometable;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
See notes about table permissions above.&lt;br /&gt;
&lt;br /&gt;
==Create a user==&lt;br /&gt;
* https://wiki.debian.org/PostgreSql&lt;br /&gt;
&lt;br /&gt;
Note that if you have an existing db, you might want to add ownership to this user, or r/w&lt;br /&gt;
permissions.&lt;/div&gt;</summary>
		<author><name>Adminguy</name></author>
	</entry>
	<entry>
		<id>http://steakwiki.com/index.php?title=Postgres&amp;diff=993</id>
		<title>Postgres</title>
		<link rel="alternate" type="text/html" href="http://steakwiki.com/index.php?title=Postgres&amp;diff=993"/>
		<updated>2021-04-15T16:40:10Z</updated>

		<summary type="html">&lt;p&gt;Adminguy: /* Usage */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Usage==&lt;br /&gt;
&lt;br /&gt;
Most commands are found by \?&lt;br /&gt;
e.g. &lt;br /&gt;
 \dt - list tables&lt;br /&gt;
 \l  - list databases&lt;br /&gt;
 \c  - connect to db&lt;br /&gt;
Since PostgreSQL 10, psql has \gx which is the exact equivalent of mysql's \G&lt;br /&gt;
 select * from sometable \gx&lt;br /&gt;
ref:stackex&lt;br /&gt;
&lt;br /&gt;
==Backup / Restore DB==&lt;br /&gt;
===backup===&lt;br /&gt;
This will run the dump as the postgres user via su, and avoids some of the permissions errors that can creep up.&lt;br /&gt;
 # cd /tmp&lt;br /&gt;
 (just need a writeable directory, aka 777)&lt;br /&gt;
 # su -c 'pg_dump mydb &amp;gt;&amp;gt; mydb_dump_2020.sql' postgres&lt;br /&gt;
assuming you have a postgres admin user, with all rights, this will backup the db. If you are remote, you might need something similar to (localhost/ip, ports, etc specified):&lt;br /&gt;
 pg_dump -U username -h localhost databasename &amp;gt;&amp;gt; sqlfile.sql&lt;br /&gt;
ref: https://stackoverflow.com/questions/37984733/postgresql-database-export-to-sql-file&lt;br /&gt;
===restore===&lt;br /&gt;
Create the new db:&lt;br /&gt;
 su - postgres&lt;br /&gt;
 psql&lt;br /&gt;
 create database bbbtest;&lt;br /&gt;
 grant all privileges on database bbbtest to mypguser;&lt;br /&gt;
 ALTER DATABASE bbbtest OWNER TO mypguser;&lt;br /&gt;
and postgres permissions are a disaster online for getting info on (unforunately, there is nothing like mysql's ''mysql -uroot -p -e &amp;quot;grant all on db.* to 'user'@localhost identified by 'pass';&amp;quot;''). But what does work is permissions for specific tables need to be enabled for the user, so:&lt;br /&gt;
 GRANT ALL ON sometableindb TO mypguser;&lt;br /&gt;
 \quit&lt;br /&gt;
 exit&lt;br /&gt;
Now, with that file&lt;br /&gt;
 # su -c 'psql -d newdbname --set ON_ERROR_STOP=on -f ./mydb_dump_2020.sql' postgres&lt;br /&gt;
&lt;br /&gt;
If you get errors, adjust data as needed or remove the ON_ERROR_STOP (some can be ignored,&lt;br /&gt;
some can not - use discretion). At least in some cases, you can move data without worrying about postgres versions. I executed a pg_dump from 11.# and imported to 9.6 without issue. Devuan Beowulf to Ascii.&lt;br /&gt;
&lt;br /&gt;
TIP: if you don't specify -d, then the data will get uploaded to one of the preexisting DB. Not good.&lt;br /&gt;
&lt;br /&gt;
Another approach:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
-- su - postgres&lt;br /&gt;
-- -- psql&lt;br /&gt;
-- -- -- create database bbbtest;&lt;br /&gt;
-- -- -- grant all privileges on database bbbtest to root;&lt;br /&gt;
-- -- -- \quit&lt;br /&gt;
-- -- exit&lt;br /&gt;
-- psql bbbtest &amp;lt; dbmake.sql&lt;br /&gt;
-- -- select * from A1;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Verify user permissions and upload was correct====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
su - mypguser&lt;br /&gt;
psql&lt;br /&gt;
select * from sometable;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
See notes about table permissions above.&lt;br /&gt;
&lt;br /&gt;
==Create a user==&lt;br /&gt;
* https://wiki.debian.org/PostgreSql&lt;br /&gt;
&lt;br /&gt;
Note that if you have an existing db, you might want to add ownership to this user, or r/w&lt;br /&gt;
permissions.&lt;/div&gt;</summary>
		<author><name>Adminguy</name></author>
	</entry>
	<entry>
		<id>http://steakwiki.com/index.php?title=Postgres&amp;diff=992</id>
		<title>Postgres</title>
		<link rel="alternate" type="text/html" href="http://steakwiki.com/index.php?title=Postgres&amp;diff=992"/>
		<updated>2021-04-15T16:39:23Z</updated>

		<summary type="html">&lt;p&gt;Adminguy: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Usage==&lt;br /&gt;
&lt;br /&gt;
Since PostgreSQL 10, psql has \gx which is the exact equivalent of mysql's \G&lt;br /&gt;
 select * from sometable \gx&lt;br /&gt;
ref:stackex&lt;br /&gt;
&lt;br /&gt;
==Backup / Restore DB==&lt;br /&gt;
===backup===&lt;br /&gt;
This will run the dump as the postgres user via su, and avoids some of the permissions errors that can creep up.&lt;br /&gt;
 # cd /tmp&lt;br /&gt;
 (just need a writeable directory, aka 777)&lt;br /&gt;
 # su -c 'pg_dump mydb &amp;gt;&amp;gt; mydb_dump_2020.sql' postgres&lt;br /&gt;
assuming you have a postgres admin user, with all rights, this will backup the db. If you are remote, you might need something similar to (localhost/ip, ports, etc specified):&lt;br /&gt;
 pg_dump -U username -h localhost databasename &amp;gt;&amp;gt; sqlfile.sql&lt;br /&gt;
ref: https://stackoverflow.com/questions/37984733/postgresql-database-export-to-sql-file&lt;br /&gt;
===restore===&lt;br /&gt;
Create the new db:&lt;br /&gt;
 su - postgres&lt;br /&gt;
 psql&lt;br /&gt;
 create database bbbtest;&lt;br /&gt;
 grant all privileges on database bbbtest to mypguser;&lt;br /&gt;
 ALTER DATABASE bbbtest OWNER TO mypguser;&lt;br /&gt;
and postgres permissions are a disaster online for getting info on (unforunately, there is nothing like mysql's ''mysql -uroot -p -e &amp;quot;grant all on db.* to 'user'@localhost identified by 'pass';&amp;quot;''). But what does work is permissions for specific tables need to be enabled for the user, so:&lt;br /&gt;
 GRANT ALL ON sometableindb TO mypguser;&lt;br /&gt;
 \quit&lt;br /&gt;
 exit&lt;br /&gt;
Now, with that file&lt;br /&gt;
 # su -c 'psql -d newdbname --set ON_ERROR_STOP=on -f ./mydb_dump_2020.sql' postgres&lt;br /&gt;
&lt;br /&gt;
If you get errors, adjust data as needed or remove the ON_ERROR_STOP (some can be ignored,&lt;br /&gt;
some can not - use discretion). At least in some cases, you can move data without worrying about postgres versions. I executed a pg_dump from 11.# and imported to 9.6 without issue. Devuan Beowulf to Ascii.&lt;br /&gt;
&lt;br /&gt;
TIP: if you don't specify -d, then the data will get uploaded to one of the preexisting DB. Not good.&lt;br /&gt;
&lt;br /&gt;
Another approach:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
-- su - postgres&lt;br /&gt;
-- -- psql&lt;br /&gt;
-- -- -- create database bbbtest;&lt;br /&gt;
-- -- -- grant all privileges on database bbbtest to root;&lt;br /&gt;
-- -- -- \quit&lt;br /&gt;
-- -- exit&lt;br /&gt;
-- psql bbbtest &amp;lt; dbmake.sql&lt;br /&gt;
-- -- select * from A1;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Verify user permissions and upload was correct====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
su - mypguser&lt;br /&gt;
psql&lt;br /&gt;
select * from sometable;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
See notes about table permissions above.&lt;br /&gt;
&lt;br /&gt;
==Create a user==&lt;br /&gt;
* https://wiki.debian.org/PostgreSql&lt;br /&gt;
&lt;br /&gt;
Note that if you have an existing db, you might want to add ownership to this user, or r/w&lt;br /&gt;
permissions.&lt;/div&gt;</summary>
		<author><name>Adminguy</name></author>
	</entry>
	<entry>
		<id>http://steakwiki.com/index.php?title=Zencart_docker_compose&amp;diff=991</id>
		<title>Zencart docker compose</title>
		<link rel="alternate" type="text/html" href="http://steakwiki.com/index.php?title=Zencart_docker_compose&amp;diff=991"/>
		<updated>2021-03-16T08:20:57Z</updated>

		<summary type="html">&lt;p&gt;Adminguy: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This was adapted from someone else online. I forget now who. Their example wasn't 100% working.&lt;br /&gt;
&lt;br /&gt;
I'll put this on my git as well.&lt;br /&gt;
http://git.steakelectronics.com/adminguy/Zencart_Docker_Compose&lt;br /&gt;
&lt;br /&gt;
Here we go:&lt;br /&gt;
Readme:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# zencart on docker&lt;br /&gt;
&lt;br /&gt;
Release 1.57c&lt;br /&gt;
Debian 10&lt;br /&gt;
MariaDB 10.5&lt;br /&gt;
php7.3&lt;br /&gt;
&lt;br /&gt;
5+ hours of work.&lt;br /&gt;
Maybe should've just used a turnkey appliance. Maybe... Maybe not.&lt;br /&gt;
&lt;br /&gt;
# tips&lt;br /&gt;
docker exec -it zencart /bin/bash&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Dockerfile:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
FROM debian:10&lt;br /&gt;
&lt;br /&gt;
RUN apt-get update &amp;amp;&amp;amp; apt-get install -y \&lt;br /&gt;
       libapache2-mod-php7.3 \&lt;br /&gt;
       curl \&lt;br /&gt;
       unzip \&lt;br /&gt;
       apt-utils \&lt;br /&gt;
       zlib1g-dev \&lt;br /&gt;
       libpng-dev \&lt;br /&gt;
       libmcrypt-dev \&lt;br /&gt;
       libzip-dev \&lt;br /&gt;
       zip&lt;br /&gt;
&lt;br /&gt;
RUN apt-get install -y \&lt;br /&gt;
    php7.3-mysql \&lt;br /&gt;
    php-zip \&lt;br /&gt;
    php7.3-gd \&lt;br /&gt;
    php7.3-dev \&lt;br /&gt;
    php7.3-opcache \&lt;br /&gt;
    php7.3-curl \&lt;br /&gt;
    &amp;amp;&amp;amp; pecl install mcrypt-1.0.2&lt;br /&gt;
&lt;br /&gt;
RUN a2enmod rewrite&lt;br /&gt;
RUN a2enmod ssl&lt;br /&gt;
&lt;br /&gt;
ENV APACHE_RUN_USER www-data&lt;br /&gt;
ENV APACHE_RUN_GROUP www-data&lt;br /&gt;
ENV APACHE_LOG_DIR /var/log/apache2&lt;br /&gt;
ENV APACHE_PID_FILE /var/run/apache2.pid&lt;br /&gt;
ENV APACHE_RUN_DIR /var/www/html/&lt;br /&gt;
ENV APACHE_LOCK_DIR /var/lock/apache2&lt;br /&gt;
&lt;br /&gt;
WORKDIR /tmp&lt;br /&gt;
RUN curl -LO https://sourceforge.net/projects/zencart/files/CURRENT%20-%20Zen%20Cart%201.5.x%20Series/zen-cart-v1.5.7c-03052021.zip/download \&lt;br /&gt;
    &amp;amp;&amp;amp; unzip /tmp/download \&lt;br /&gt;
    &amp;amp;&amp;amp; mv /tmp/zen-cart*/* /var/www/html/. \&lt;br /&gt;
    &amp;amp;&amp;amp; cd /var/www/html \&lt;br /&gt;
    &amp;amp;&amp;amp; cp includes/dist-configure.php includes/configure.php \&lt;br /&gt;
    &amp;amp;&amp;amp; cp admin/includes/dist-configure.php admin/includes/configure.php \&lt;br /&gt;
    &amp;amp;&amp;amp; chown -R www-data:www-data /var/www/html&lt;br /&gt;
&lt;br /&gt;
RUN echo '[Date]' &amp;gt; /etc/php/7.3/apache2/conf.d/timezone.ini \&lt;br /&gt;
 &amp;amp;&amp;amp; echo 'date.timezone = &amp;quot;America/New_York&amp;quot;' &amp;gt;&amp;gt; /etc/php/7.3/apache2/conf.d/timezone.ini&lt;br /&gt;
&lt;br /&gt;
RUN ln -s /etc/apache2/sites-available/default-ssl.conf /etc/apache2/sites-enabled/default-ssl.conf&lt;br /&gt;
&lt;br /&gt;
COPY ./newapache2conf /etc/apache2/apache2.conf&lt;br /&gt;
&lt;br /&gt;
CMD [&amp;quot;/usr/sbin/apache2&amp;quot;, &amp;quot;-D&amp;quot;, &amp;quot;FOREGROUND&amp;quot;]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
New apache2 conf (see dockerfile for where this goes).&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# This is the main Apache server configuration file.  It contains the&lt;br /&gt;
# configuration directives that give the server its instructions.&lt;br /&gt;
# See http://httpd.apache.org/docs/2.4/ for detailed information about&lt;br /&gt;
# the directives and /usr/share/doc/apache2/README.Debian about Debian specific&lt;br /&gt;
# hints.&lt;br /&gt;
#&lt;br /&gt;
#&lt;br /&gt;
# Summary of how the Apache 2 configuration works in Debian:&lt;br /&gt;
# The Apache 2 web server configuration in Debian is quite different to&lt;br /&gt;
# upstream's suggested way to configure the web server. This is because Debian's&lt;br /&gt;
# default Apache2 installation attempts to make adding and removing modules,&lt;br /&gt;
# virtual hosts, and extra configuration directives as flexible as possible, in&lt;br /&gt;
# order to make automating the changes and administering the server as easy as&lt;br /&gt;
# possible.&lt;br /&gt;
&lt;br /&gt;
# It is split into several files forming the configuration hierarchy outlined&lt;br /&gt;
# below, all located in the /etc/apache2/ directory:&lt;br /&gt;
#&lt;br /&gt;
#	/etc/apache2/&lt;br /&gt;
#	|-- apache2.conf&lt;br /&gt;
#	|	`--  ports.conf&lt;br /&gt;
#	|-- mods-enabled&lt;br /&gt;
#	|	|-- *.load&lt;br /&gt;
#	|	`-- *.conf&lt;br /&gt;
#	|-- conf-enabled&lt;br /&gt;
#	|	`-- *.conf&lt;br /&gt;
# 	`-- sites-enabled&lt;br /&gt;
#	 	`-- *.conf&lt;br /&gt;
#&lt;br /&gt;
#&lt;br /&gt;
# * apache2.conf is the main configuration file (this file). It puts the pieces&lt;br /&gt;
#   together by including all remaining configuration files when starting up the&lt;br /&gt;
#   web server.&lt;br /&gt;
#&lt;br /&gt;
# * ports.conf is always included from the main configuration file. It is&lt;br /&gt;
#   supposed to determine listening ports for incoming connections which can be&lt;br /&gt;
#   customized anytime.&lt;br /&gt;
#&lt;br /&gt;
# * Configuration files in the mods-enabled/, conf-enabled/ and sites-enabled/&lt;br /&gt;
#   directories contain particular configuration snippets which manage modules,&lt;br /&gt;
#   global configuration fragments, or virtual host configurations,&lt;br /&gt;
#   respectively.&lt;br /&gt;
#&lt;br /&gt;
#   They are activated by symlinking available configuration files from their&lt;br /&gt;
#   respective *-available/ counterparts. These should be managed by using our&lt;br /&gt;
#   helpers a2enmod/a2dismod, a2ensite/a2dissite and a2enconf/a2disconf. See&lt;br /&gt;
#   their respective man pages for detailed information.&lt;br /&gt;
#&lt;br /&gt;
# * The binary is called apache2. Due to the use of environment variables, in&lt;br /&gt;
#   the default configuration, apache2 needs to be started/stopped with&lt;br /&gt;
#   /etc/init.d/apache2 or apache2ctl. Calling /usr/bin/apache2 directly will not&lt;br /&gt;
#   work with the default configuration.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# Global configuration&lt;br /&gt;
#&lt;br /&gt;
&lt;br /&gt;
#&lt;br /&gt;
# ServerRoot: The top of the directory tree under which the server's&lt;br /&gt;
# configuration, error, and log files are kept.&lt;br /&gt;
#&lt;br /&gt;
# NOTE!  If you intend to place this on an NFS (or otherwise network)&lt;br /&gt;
# mounted filesystem then please read the Mutex documentation (available&lt;br /&gt;
# at &amp;lt;URL:http://httpd.apache.org/docs/2.4/mod/core.html#mutex&amp;gt;);&lt;br /&gt;
# you will save yourself a lot of trouble.&lt;br /&gt;
#&lt;br /&gt;
# Do NOT add a slash at the end of the directory path.&lt;br /&gt;
#&lt;br /&gt;
#ServerRoot &amp;quot;/etc/apache2&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#&lt;br /&gt;
# The accept serialization lock file MUST BE STORED ON A LOCAL DISK.&lt;br /&gt;
#&lt;br /&gt;
#Mutex file:${APACHE_LOCK_DIR} default&lt;br /&gt;
&lt;br /&gt;
#&lt;br /&gt;
# The directory where shm and other runtime files will be stored.&lt;br /&gt;
#&lt;br /&gt;
&lt;br /&gt;
DefaultRuntimeDir ${APACHE_RUN_DIR}&lt;br /&gt;
&lt;br /&gt;
#&lt;br /&gt;
# PidFile: The file in which the server should record its process&lt;br /&gt;
# identification number when it starts.&lt;br /&gt;
# This needs to be set in /etc/apache2/envvars&lt;br /&gt;
#&lt;br /&gt;
PidFile ${APACHE_PID_FILE}&lt;br /&gt;
&lt;br /&gt;
#&lt;br /&gt;
# Timeout: The number of seconds before receives and sends time out.&lt;br /&gt;
#&lt;br /&gt;
Timeout 300&lt;br /&gt;
&lt;br /&gt;
#&lt;br /&gt;
# KeepAlive: Whether or not to allow persistent connections (more than&lt;br /&gt;
# one request per connection). Set to &amp;quot;Off&amp;quot; to deactivate.&lt;br /&gt;
#&lt;br /&gt;
KeepAlive On&lt;br /&gt;
&lt;br /&gt;
#&lt;br /&gt;
# MaxKeepAliveRequests: The maximum number of requests to allow&lt;br /&gt;
# during a persistent connection. Set to 0 to allow an unlimited amount.&lt;br /&gt;
# We recommend you leave this number high, for maximum performance.&lt;br /&gt;
#&lt;br /&gt;
MaxKeepAliveRequests 100&lt;br /&gt;
&lt;br /&gt;
#&lt;br /&gt;
# KeepAliveTimeout: Number of seconds to wait for the next request from the&lt;br /&gt;
# same client on the same connection.&lt;br /&gt;
#&lt;br /&gt;
KeepAliveTimeout 5&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# These need to be set in /etc/apache2/envvars&lt;br /&gt;
User ${APACHE_RUN_USER}&lt;br /&gt;
Group ${APACHE_RUN_GROUP}&lt;br /&gt;
&lt;br /&gt;
#&lt;br /&gt;
# HostnameLookups: Log the names of clients or just their IP addresses&lt;br /&gt;
# e.g., www.apache.org (on) or 204.62.129.132 (off).&lt;br /&gt;
# The default is off because it'd be overall better for the net if people&lt;br /&gt;
# had to knowingly turn this feature on, since enabling it means that&lt;br /&gt;
# each client request will result in AT LEAST one lookup request to the&lt;br /&gt;
# nameserver.&lt;br /&gt;
#&lt;br /&gt;
HostnameLookups Off&lt;br /&gt;
&lt;br /&gt;
# ErrorLog: The location of the error log file.&lt;br /&gt;
# If you do not specify an ErrorLog directive within a &amp;lt;VirtualHost&amp;gt;&lt;br /&gt;
# container, error messages relating to that virtual host will be&lt;br /&gt;
# logged here.  If you *do* define an error logfile for a &amp;lt;VirtualHost&amp;gt;&lt;br /&gt;
# container, that host's errors will be logged there and not here.&lt;br /&gt;
#&lt;br /&gt;
ErrorLog ${APACHE_LOG_DIR}/error.log&lt;br /&gt;
&lt;br /&gt;
#&lt;br /&gt;
# LogLevel: Control the severity of messages logged to the error_log.&lt;br /&gt;
# Available values: trace8, ..., trace1, debug, info, notice, warn,&lt;br /&gt;
# error, crit, alert, emerg.&lt;br /&gt;
# It is also possible to configure the log level for particular modules, e.g.&lt;br /&gt;
# &amp;quot;LogLevel info ssl:warn&amp;quot;&lt;br /&gt;
#&lt;br /&gt;
LogLevel warn&lt;br /&gt;
&lt;br /&gt;
# Include module configuration:&lt;br /&gt;
IncludeOptional mods-enabled/*.load&lt;br /&gt;
IncludeOptional mods-enabled/*.conf&lt;br /&gt;
&lt;br /&gt;
# Include list of ports to listen on&lt;br /&gt;
Include ports.conf&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# Sets the default security model of the Apache2 HTTPD server. It does&lt;br /&gt;
# not allow access to the root filesystem outside of /usr/share and /var/www.&lt;br /&gt;
# The former is used by web applications packaged in Debian,&lt;br /&gt;
# the latter may be used for local directories served by the web server. If&lt;br /&gt;
# your system is serving content from a sub-directory in /srv you must allow&lt;br /&gt;
# access here, or in any related virtual host.&lt;br /&gt;
&amp;lt;Directory /&amp;gt;&lt;br /&gt;
	Options FollowSymLinks&lt;br /&gt;
	AllowOverride None&lt;br /&gt;
	Require all denied&lt;br /&gt;
&amp;lt;/Directory&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;Directory /usr/share&amp;gt;&lt;br /&gt;
	AllowOverride None&lt;br /&gt;
	Require all granted&lt;br /&gt;
&amp;lt;/Directory&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;Directory /var/www/&amp;gt;&lt;br /&gt;
	Options Indexes FollowSymLinks&lt;br /&gt;
	AllowOverride All&lt;br /&gt;
	Require all granted&lt;br /&gt;
&amp;lt;/Directory&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#&amp;lt;Directory /srv/&amp;gt;&lt;br /&gt;
#	Options Indexes FollowSymLinks&lt;br /&gt;
#	AllowOverride None&lt;br /&gt;
#	Require all granted&lt;br /&gt;
#&amp;lt;/Directory&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# AccessFileName: The name of the file to look for in each directory&lt;br /&gt;
# for additional configuration directives.  See also the AllowOverride&lt;br /&gt;
# directive.&lt;br /&gt;
#&lt;br /&gt;
AccessFileName .htaccess&lt;br /&gt;
&lt;br /&gt;
#&lt;br /&gt;
# The following lines prevent .htaccess and .htpasswd files from being&lt;br /&gt;
# viewed by Web clients.&lt;br /&gt;
#&lt;br /&gt;
&amp;lt;FilesMatch &amp;quot;^\.ht&amp;quot;&amp;gt;&lt;br /&gt;
	Require all denied&lt;br /&gt;
&amp;lt;/FilesMatch&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
#&lt;br /&gt;
# The following directives define some format nicknames for use with&lt;br /&gt;
# a CustomLog directive.&lt;br /&gt;
#&lt;br /&gt;
# These deviate from the Common Log Format definitions in that they use %O&lt;br /&gt;
# (the actual bytes sent including headers) instead of %b (the size of the&lt;br /&gt;
# requested file), because the latter makes it impossible to detect partial&lt;br /&gt;
# requests.&lt;br /&gt;
#&lt;br /&gt;
# Note that the use of %{X-Forwarded-For}i instead of %h is not recommended.&lt;br /&gt;
# Use mod_remoteip instead.&lt;br /&gt;
#&lt;br /&gt;
LogFormat &amp;quot;%v:%p %h %l %u %t \&amp;quot;%r\&amp;quot; %&amp;gt;s %O \&amp;quot;%{Referer}i\&amp;quot; \&amp;quot;%{User-Agent}i\&amp;quot;&amp;quot; vhost_combined&lt;br /&gt;
LogFormat &amp;quot;%h %l %u %t \&amp;quot;%r\&amp;quot; %&amp;gt;s %O \&amp;quot;%{Referer}i\&amp;quot; \&amp;quot;%{User-Agent}i\&amp;quot;&amp;quot; combined&lt;br /&gt;
LogFormat &amp;quot;%h %l %u %t \&amp;quot;%r\&amp;quot; %&amp;gt;s %O&amp;quot; common&lt;br /&gt;
LogFormat &amp;quot;%{Referer}i -&amp;gt; %U&amp;quot; referer&lt;br /&gt;
LogFormat &amp;quot;%{User-agent}i&amp;quot; agent&lt;br /&gt;
&lt;br /&gt;
# Include of directories ignores editors' and dpkg's backup files,&lt;br /&gt;
# see README.Debian for details.&lt;br /&gt;
&lt;br /&gt;
# Include generic snippets of statements&lt;br /&gt;
IncludeOptional conf-enabled/*.conf&lt;br /&gt;
&lt;br /&gt;
# Include the virtual host configurations:&lt;br /&gt;
IncludeOptional sites-enabled/*.conf&lt;br /&gt;
&lt;br /&gt;
# vim: syntax=apache ts=4 sw=4 sts=4 sr noet&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
docker-compose.yml:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
version: '3'&lt;br /&gt;
services:&lt;br /&gt;
  z157:&lt;br /&gt;
    build: ./app/&lt;br /&gt;
    container_name: zencart_157c&lt;br /&gt;
    ports:&lt;br /&gt;
      - &amp;quot;80:80&amp;quot;&lt;br /&gt;
      - &amp;quot;443:443&amp;quot;&lt;br /&gt;
    depends_on:&lt;br /&gt;
      - datab&lt;br /&gt;
  datab:&lt;br /&gt;
    image: mariadb:10.5&lt;br /&gt;
    container_name: db_zencart2&lt;br /&gt;
    volumes:&lt;br /&gt;
      - ./dbdata:/var/lib/mysql&lt;br /&gt;
    environment:&lt;br /&gt;
      MYSQL_ROOT_PASSWORD: ROOTPW&lt;br /&gt;
      MYSQL_USER: user&lt;br /&gt;
      MYSQL_PASSWORD: pass&lt;br /&gt;
      MYSQL_DATABASE: zencart&lt;br /&gt;
    ports:&lt;br /&gt;
      - &amp;quot;3306:3306&amp;quot;&lt;br /&gt;
#volumes:&lt;br /&gt;
#  db-volume:&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Adminguy</name></author>
	</entry>
	<entry>
		<id>http://steakwiki.com/index.php?title=Zencart_docker_compose&amp;diff=990</id>
		<title>Zencart docker compose</title>
		<link rel="alternate" type="text/html" href="http://steakwiki.com/index.php?title=Zencart_docker_compose&amp;diff=990"/>
		<updated>2021-03-16T08:05:32Z</updated>

		<summary type="html">&lt;p&gt;Adminguy: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This was adapted from someone else online. I forget now who. Their example wasn't 100% working.&lt;br /&gt;
&lt;br /&gt;
I'll put this on my git as well.&lt;br /&gt;
&lt;br /&gt;
Here we go:&lt;br /&gt;
Readme:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# zencart on docker&lt;br /&gt;
&lt;br /&gt;
Release 1.57c&lt;br /&gt;
Debian 10&lt;br /&gt;
MariaDB 10.5&lt;br /&gt;
php7.3&lt;br /&gt;
&lt;br /&gt;
5+ hours of work.&lt;br /&gt;
Maybe should've just used a turnkey appliance. Maybe... Maybe not.&lt;br /&gt;
&lt;br /&gt;
# tips&lt;br /&gt;
docker exec -it zencart /bin/bash&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Dockerfile:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
FROM debian:10&lt;br /&gt;
&lt;br /&gt;
RUN apt-get update &amp;amp;&amp;amp; apt-get install -y \&lt;br /&gt;
       libapache2-mod-php7.3 \&lt;br /&gt;
       curl \&lt;br /&gt;
       unzip \&lt;br /&gt;
       apt-utils \&lt;br /&gt;
       zlib1g-dev \&lt;br /&gt;
       libpng-dev \&lt;br /&gt;
       libmcrypt-dev \&lt;br /&gt;
       libzip-dev \&lt;br /&gt;
       zip&lt;br /&gt;
&lt;br /&gt;
RUN apt-get install -y \&lt;br /&gt;
    php7.3-mysql \&lt;br /&gt;
    php-zip \&lt;br /&gt;
    php7.3-gd \&lt;br /&gt;
    php7.3-dev \&lt;br /&gt;
    php7.3-opcache \&lt;br /&gt;
    php7.3-curl \&lt;br /&gt;
    &amp;amp;&amp;amp; pecl install mcrypt-1.0.2&lt;br /&gt;
&lt;br /&gt;
RUN a2enmod rewrite&lt;br /&gt;
RUN a2enmod ssl&lt;br /&gt;
&lt;br /&gt;
ENV APACHE_RUN_USER www-data&lt;br /&gt;
ENV APACHE_RUN_GROUP www-data&lt;br /&gt;
ENV APACHE_LOG_DIR /var/log/apache2&lt;br /&gt;
ENV APACHE_PID_FILE /var/run/apache2.pid&lt;br /&gt;
ENV APACHE_RUN_DIR /var/www/html/&lt;br /&gt;
ENV APACHE_LOCK_DIR /var/lock/apache2&lt;br /&gt;
&lt;br /&gt;
WORKDIR /tmp&lt;br /&gt;
RUN curl -LO https://sourceforge.net/projects/zencart/files/CURRENT%20-%20Zen%20Cart%201.5.x%20Series/zen-cart-v1.5.7c-03052021.zip/download \&lt;br /&gt;
    &amp;amp;&amp;amp; unzip /tmp/download \&lt;br /&gt;
    &amp;amp;&amp;amp; mv /tmp/zen-cart*/* /var/www/html/. \&lt;br /&gt;
    &amp;amp;&amp;amp; cd /var/www/html \&lt;br /&gt;
    &amp;amp;&amp;amp; cp includes/dist-configure.php includes/configure.php \&lt;br /&gt;
    &amp;amp;&amp;amp; cp admin/includes/dist-configure.php admin/includes/configure.php \&lt;br /&gt;
    &amp;amp;&amp;amp; chown -R www-data:www-data /var/www/html&lt;br /&gt;
&lt;br /&gt;
RUN echo '[Date]' &amp;gt; /etc/php/7.3/apache2/conf.d/timezone.ini \&lt;br /&gt;
 &amp;amp;&amp;amp; echo 'date.timezone = &amp;quot;America/New_York&amp;quot;' &amp;gt;&amp;gt; /etc/php/7.3/apache2/conf.d/timezone.ini&lt;br /&gt;
&lt;br /&gt;
RUN ln -s /etc/apache2/sites-available/default-ssl.conf /etc/apache2/sites-enabled/default-ssl.conf&lt;br /&gt;
&lt;br /&gt;
COPY ./newapache2conf /etc/apache2/apache2.conf&lt;br /&gt;
&lt;br /&gt;
CMD [&amp;quot;/usr/sbin/apache2&amp;quot;, &amp;quot;-D&amp;quot;, &amp;quot;FOREGROUND&amp;quot;]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
New apache2 conf (see dockerfile for where this goes).&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# This is the main Apache server configuration file.  It contains the&lt;br /&gt;
# configuration directives that give the server its instructions.&lt;br /&gt;
# See http://httpd.apache.org/docs/2.4/ for detailed information about&lt;br /&gt;
# the directives and /usr/share/doc/apache2/README.Debian about Debian specific&lt;br /&gt;
# hints.&lt;br /&gt;
#&lt;br /&gt;
#&lt;br /&gt;
# Summary of how the Apache 2 configuration works in Debian:&lt;br /&gt;
# The Apache 2 web server configuration in Debian is quite different to&lt;br /&gt;
# upstream's suggested way to configure the web server. This is because Debian's&lt;br /&gt;
# default Apache2 installation attempts to make adding and removing modules,&lt;br /&gt;
# virtual hosts, and extra configuration directives as flexible as possible, in&lt;br /&gt;
# order to make automating the changes and administering the server as easy as&lt;br /&gt;
# possible.&lt;br /&gt;
&lt;br /&gt;
# It is split into several files forming the configuration hierarchy outlined&lt;br /&gt;
# below, all located in the /etc/apache2/ directory:&lt;br /&gt;
#&lt;br /&gt;
#	/etc/apache2/&lt;br /&gt;
#	|-- apache2.conf&lt;br /&gt;
#	|	`--  ports.conf&lt;br /&gt;
#	|-- mods-enabled&lt;br /&gt;
#	|	|-- *.load&lt;br /&gt;
#	|	`-- *.conf&lt;br /&gt;
#	|-- conf-enabled&lt;br /&gt;
#	|	`-- *.conf&lt;br /&gt;
# 	`-- sites-enabled&lt;br /&gt;
#	 	`-- *.conf&lt;br /&gt;
#&lt;br /&gt;
#&lt;br /&gt;
# * apache2.conf is the main configuration file (this file). It puts the pieces&lt;br /&gt;
#   together by including all remaining configuration files when starting up the&lt;br /&gt;
#   web server.&lt;br /&gt;
#&lt;br /&gt;
# * ports.conf is always included from the main configuration file. It is&lt;br /&gt;
#   supposed to determine listening ports for incoming connections which can be&lt;br /&gt;
#   customized anytime.&lt;br /&gt;
#&lt;br /&gt;
# * Configuration files in the mods-enabled/, conf-enabled/ and sites-enabled/&lt;br /&gt;
#   directories contain particular configuration snippets which manage modules,&lt;br /&gt;
#   global configuration fragments, or virtual host configurations,&lt;br /&gt;
#   respectively.&lt;br /&gt;
#&lt;br /&gt;
#   They are activated by symlinking available configuration files from their&lt;br /&gt;
#   respective *-available/ counterparts. These should be managed by using our&lt;br /&gt;
#   helpers a2enmod/a2dismod, a2ensite/a2dissite and a2enconf/a2disconf. See&lt;br /&gt;
#   their respective man pages for detailed information.&lt;br /&gt;
#&lt;br /&gt;
# * The binary is called apache2. Due to the use of environment variables, in&lt;br /&gt;
#   the default configuration, apache2 needs to be started/stopped with&lt;br /&gt;
#   /etc/init.d/apache2 or apache2ctl. Calling /usr/bin/apache2 directly will not&lt;br /&gt;
#   work with the default configuration.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# Global configuration&lt;br /&gt;
#&lt;br /&gt;
&lt;br /&gt;
#&lt;br /&gt;
# ServerRoot: The top of the directory tree under which the server's&lt;br /&gt;
# configuration, error, and log files are kept.&lt;br /&gt;
#&lt;br /&gt;
# NOTE!  If you intend to place this on an NFS (or otherwise network)&lt;br /&gt;
# mounted filesystem then please read the Mutex documentation (available&lt;br /&gt;
# at &amp;lt;URL:http://httpd.apache.org/docs/2.4/mod/core.html#mutex&amp;gt;);&lt;br /&gt;
# you will save yourself a lot of trouble.&lt;br /&gt;
#&lt;br /&gt;
# Do NOT add a slash at the end of the directory path.&lt;br /&gt;
#&lt;br /&gt;
#ServerRoot &amp;quot;/etc/apache2&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#&lt;br /&gt;
# The accept serialization lock file MUST BE STORED ON A LOCAL DISK.&lt;br /&gt;
#&lt;br /&gt;
#Mutex file:${APACHE_LOCK_DIR} default&lt;br /&gt;
&lt;br /&gt;
#&lt;br /&gt;
# The directory where shm and other runtime files will be stored.&lt;br /&gt;
#&lt;br /&gt;
&lt;br /&gt;
DefaultRuntimeDir ${APACHE_RUN_DIR}&lt;br /&gt;
&lt;br /&gt;
#&lt;br /&gt;
# PidFile: The file in which the server should record its process&lt;br /&gt;
# identification number when it starts.&lt;br /&gt;
# This needs to be set in /etc/apache2/envvars&lt;br /&gt;
#&lt;br /&gt;
PidFile ${APACHE_PID_FILE}&lt;br /&gt;
&lt;br /&gt;
#&lt;br /&gt;
# Timeout: The number of seconds before receives and sends time out.&lt;br /&gt;
#&lt;br /&gt;
Timeout 300&lt;br /&gt;
&lt;br /&gt;
#&lt;br /&gt;
# KeepAlive: Whether or not to allow persistent connections (more than&lt;br /&gt;
# one request per connection). Set to &amp;quot;Off&amp;quot; to deactivate.&lt;br /&gt;
#&lt;br /&gt;
KeepAlive On&lt;br /&gt;
&lt;br /&gt;
#&lt;br /&gt;
# MaxKeepAliveRequests: The maximum number of requests to allow&lt;br /&gt;
# during a persistent connection. Set to 0 to allow an unlimited amount.&lt;br /&gt;
# We recommend you leave this number high, for maximum performance.&lt;br /&gt;
#&lt;br /&gt;
MaxKeepAliveRequests 100&lt;br /&gt;
&lt;br /&gt;
#&lt;br /&gt;
# KeepAliveTimeout: Number of seconds to wait for the next request from the&lt;br /&gt;
# same client on the same connection.&lt;br /&gt;
#&lt;br /&gt;
KeepAliveTimeout 5&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# These need to be set in /etc/apache2/envvars&lt;br /&gt;
User ${APACHE_RUN_USER}&lt;br /&gt;
Group ${APACHE_RUN_GROUP}&lt;br /&gt;
&lt;br /&gt;
#&lt;br /&gt;
# HostnameLookups: Log the names of clients or just their IP addresses&lt;br /&gt;
# e.g., www.apache.org (on) or 204.62.129.132 (off).&lt;br /&gt;
# The default is off because it'd be overall better for the net if people&lt;br /&gt;
# had to knowingly turn this feature on, since enabling it means that&lt;br /&gt;
# each client request will result in AT LEAST one lookup request to the&lt;br /&gt;
# nameserver.&lt;br /&gt;
#&lt;br /&gt;
HostnameLookups Off&lt;br /&gt;
&lt;br /&gt;
# ErrorLog: The location of the error log file.&lt;br /&gt;
# If you do not specify an ErrorLog directive within a &amp;lt;VirtualHost&amp;gt;&lt;br /&gt;
# container, error messages relating to that virtual host will be&lt;br /&gt;
# logged here.  If you *do* define an error logfile for a &amp;lt;VirtualHost&amp;gt;&lt;br /&gt;
# container, that host's errors will be logged there and not here.&lt;br /&gt;
#&lt;br /&gt;
ErrorLog ${APACHE_LOG_DIR}/error.log&lt;br /&gt;
&lt;br /&gt;
#&lt;br /&gt;
# LogLevel: Control the severity of messages logged to the error_log.&lt;br /&gt;
# Available values: trace8, ..., trace1, debug, info, notice, warn,&lt;br /&gt;
# error, crit, alert, emerg.&lt;br /&gt;
# It is also possible to configure the log level for particular modules, e.g.&lt;br /&gt;
# &amp;quot;LogLevel info ssl:warn&amp;quot;&lt;br /&gt;
#&lt;br /&gt;
LogLevel warn&lt;br /&gt;
&lt;br /&gt;
# Include module configuration:&lt;br /&gt;
IncludeOptional mods-enabled/*.load&lt;br /&gt;
IncludeOptional mods-enabled/*.conf&lt;br /&gt;
&lt;br /&gt;
# Include list of ports to listen on&lt;br /&gt;
Include ports.conf&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# Sets the default security model of the Apache2 HTTPD server. It does&lt;br /&gt;
# not allow access to the root filesystem outside of /usr/share and /var/www.&lt;br /&gt;
# The former is used by web applications packaged in Debian,&lt;br /&gt;
# the latter may be used for local directories served by the web server. If&lt;br /&gt;
# your system is serving content from a sub-directory in /srv you must allow&lt;br /&gt;
# access here, or in any related virtual host.&lt;br /&gt;
&amp;lt;Directory /&amp;gt;&lt;br /&gt;
	Options FollowSymLinks&lt;br /&gt;
	AllowOverride None&lt;br /&gt;
	Require all denied&lt;br /&gt;
&amp;lt;/Directory&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;Directory /usr/share&amp;gt;&lt;br /&gt;
	AllowOverride None&lt;br /&gt;
	Require all granted&lt;br /&gt;
&amp;lt;/Directory&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;Directory /var/www/&amp;gt;&lt;br /&gt;
	Options Indexes FollowSymLinks&lt;br /&gt;
	AllowOverride All&lt;br /&gt;
	Require all granted&lt;br /&gt;
&amp;lt;/Directory&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#&amp;lt;Directory /srv/&amp;gt;&lt;br /&gt;
#	Options Indexes FollowSymLinks&lt;br /&gt;
#	AllowOverride None&lt;br /&gt;
#	Require all granted&lt;br /&gt;
#&amp;lt;/Directory&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# AccessFileName: The name of the file to look for in each directory&lt;br /&gt;
# for additional configuration directives.  See also the AllowOverride&lt;br /&gt;
# directive.&lt;br /&gt;
#&lt;br /&gt;
AccessFileName .htaccess&lt;br /&gt;
&lt;br /&gt;
#&lt;br /&gt;
# The following lines prevent .htaccess and .htpasswd files from being&lt;br /&gt;
# viewed by Web clients.&lt;br /&gt;
#&lt;br /&gt;
&amp;lt;FilesMatch &amp;quot;^\.ht&amp;quot;&amp;gt;&lt;br /&gt;
	Require all denied&lt;br /&gt;
&amp;lt;/FilesMatch&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
#&lt;br /&gt;
# The following directives define some format nicknames for use with&lt;br /&gt;
# a CustomLog directive.&lt;br /&gt;
#&lt;br /&gt;
# These deviate from the Common Log Format definitions in that they use %O&lt;br /&gt;
# (the actual bytes sent including headers) instead of %b (the size of the&lt;br /&gt;
# requested file), because the latter makes it impossible to detect partial&lt;br /&gt;
# requests.&lt;br /&gt;
#&lt;br /&gt;
# Note that the use of %{X-Forwarded-For}i instead of %h is not recommended.&lt;br /&gt;
# Use mod_remoteip instead.&lt;br /&gt;
#&lt;br /&gt;
LogFormat &amp;quot;%v:%p %h %l %u %t \&amp;quot;%r\&amp;quot; %&amp;gt;s %O \&amp;quot;%{Referer}i\&amp;quot; \&amp;quot;%{User-Agent}i\&amp;quot;&amp;quot; vhost_combined&lt;br /&gt;
LogFormat &amp;quot;%h %l %u %t \&amp;quot;%r\&amp;quot; %&amp;gt;s %O \&amp;quot;%{Referer}i\&amp;quot; \&amp;quot;%{User-Agent}i\&amp;quot;&amp;quot; combined&lt;br /&gt;
LogFormat &amp;quot;%h %l %u %t \&amp;quot;%r\&amp;quot; %&amp;gt;s %O&amp;quot; common&lt;br /&gt;
LogFormat &amp;quot;%{Referer}i -&amp;gt; %U&amp;quot; referer&lt;br /&gt;
LogFormat &amp;quot;%{User-agent}i&amp;quot; agent&lt;br /&gt;
&lt;br /&gt;
# Include of directories ignores editors' and dpkg's backup files,&lt;br /&gt;
# see README.Debian for details.&lt;br /&gt;
&lt;br /&gt;
# Include generic snippets of statements&lt;br /&gt;
IncludeOptional conf-enabled/*.conf&lt;br /&gt;
&lt;br /&gt;
# Include the virtual host configurations:&lt;br /&gt;
IncludeOptional sites-enabled/*.conf&lt;br /&gt;
&lt;br /&gt;
# vim: syntax=apache ts=4 sw=4 sts=4 sr noet&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
docker-compose.yml:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
version: '3'&lt;br /&gt;
services:&lt;br /&gt;
  z157:&lt;br /&gt;
    build: ./app/&lt;br /&gt;
    container_name: zencart_157c&lt;br /&gt;
    ports:&lt;br /&gt;
      - &amp;quot;80:80&amp;quot;&lt;br /&gt;
      - &amp;quot;443:443&amp;quot;&lt;br /&gt;
    depends_on:&lt;br /&gt;
      - datab&lt;br /&gt;
  datab:&lt;br /&gt;
    image: mariadb:10.5&lt;br /&gt;
    container_name: db_zencart2&lt;br /&gt;
    volumes:&lt;br /&gt;
      - ./dbdata:/var/lib/mysql&lt;br /&gt;
    environment:&lt;br /&gt;
      MYSQL_ROOT_PASSWORD: ROOTPW&lt;br /&gt;
      MYSQL_USER: user&lt;br /&gt;
      MYSQL_PASSWORD: pass&lt;br /&gt;
      MYSQL_DATABASE: zencart&lt;br /&gt;
    ports:&lt;br /&gt;
      - &amp;quot;3306:3306&amp;quot;&lt;br /&gt;
#volumes:&lt;br /&gt;
#  db-volume:&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Adminguy</name></author>
	</entry>
	<entry>
		<id>http://steakwiki.com/index.php?title=Zencart_docker_compose&amp;diff=989</id>
		<title>Zencart docker compose</title>
		<link rel="alternate" type="text/html" href="http://steakwiki.com/index.php?title=Zencart_docker_compose&amp;diff=989"/>
		<updated>2021-03-16T08:04:49Z</updated>

		<summary type="html">&lt;p&gt;Adminguy: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This was adapted from someone else online. I forget now who. Their example wasn't 100% working.&lt;br /&gt;
&lt;br /&gt;
Here we go:&lt;br /&gt;
Readme:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# zencart on docker&lt;br /&gt;
&lt;br /&gt;
Release 1.57c&lt;br /&gt;
Debian 10&lt;br /&gt;
MariaDB 10.5&lt;br /&gt;
php7.3&lt;br /&gt;
&lt;br /&gt;
5+ hours of work.&lt;br /&gt;
Maybe should've just used a turnkey appliance. Maybe... Maybe not.&lt;br /&gt;
&lt;br /&gt;
# tips&lt;br /&gt;
docker exec -it zencart /bin/bash&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Dockerfile:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
FROM debian:10&lt;br /&gt;
&lt;br /&gt;
RUN apt-get update &amp;amp;&amp;amp; apt-get install -y \&lt;br /&gt;
       libapache2-mod-php7.3 \&lt;br /&gt;
       curl \&lt;br /&gt;
       unzip \&lt;br /&gt;
       apt-utils \&lt;br /&gt;
       zlib1g-dev \&lt;br /&gt;
       libpng-dev \&lt;br /&gt;
       libmcrypt-dev \&lt;br /&gt;
       libzip-dev \&lt;br /&gt;
       zip&lt;br /&gt;
&lt;br /&gt;
RUN apt-get install -y \&lt;br /&gt;
    php7.3-mysql \&lt;br /&gt;
    php-zip \&lt;br /&gt;
    php7.3-gd \&lt;br /&gt;
    php7.3-dev \&lt;br /&gt;
    php7.3-opcache \&lt;br /&gt;
    php7.3-curl \&lt;br /&gt;
    &amp;amp;&amp;amp; pecl install mcrypt-1.0.2&lt;br /&gt;
&lt;br /&gt;
RUN a2enmod rewrite&lt;br /&gt;
RUN a2enmod ssl&lt;br /&gt;
&lt;br /&gt;
ENV APACHE_RUN_USER www-data&lt;br /&gt;
ENV APACHE_RUN_GROUP www-data&lt;br /&gt;
ENV APACHE_LOG_DIR /var/log/apache2&lt;br /&gt;
ENV APACHE_PID_FILE /var/run/apache2.pid&lt;br /&gt;
ENV APACHE_RUN_DIR /var/www/html/&lt;br /&gt;
ENV APACHE_LOCK_DIR /var/lock/apache2&lt;br /&gt;
&lt;br /&gt;
WORKDIR /tmp&lt;br /&gt;
RUN curl -LO https://sourceforge.net/projects/zencart/files/CURRENT%20-%20Zen%20Cart%201.5.x%20Series/zen-cart-v1.5.7c-03052021.zip/download \&lt;br /&gt;
    &amp;amp;&amp;amp; unzip /tmp/download \&lt;br /&gt;
    &amp;amp;&amp;amp; mv /tmp/zen-cart*/* /var/www/html/. \&lt;br /&gt;
    &amp;amp;&amp;amp; cd /var/www/html \&lt;br /&gt;
    &amp;amp;&amp;amp; cp includes/dist-configure.php includes/configure.php \&lt;br /&gt;
    &amp;amp;&amp;amp; cp admin/includes/dist-configure.php admin/includes/configure.php \&lt;br /&gt;
    &amp;amp;&amp;amp; chown -R www-data:www-data /var/www/html&lt;br /&gt;
&lt;br /&gt;
RUN echo '[Date]' &amp;gt; /etc/php/7.3/apache2/conf.d/timezone.ini \&lt;br /&gt;
 &amp;amp;&amp;amp; echo 'date.timezone = &amp;quot;America/New_York&amp;quot;' &amp;gt;&amp;gt; /etc/php/7.3/apache2/conf.d/timezone.ini&lt;br /&gt;
&lt;br /&gt;
RUN ln -s /etc/apache2/sites-available/default-ssl.conf /etc/apache2/sites-enabled/default-ssl.conf&lt;br /&gt;
&lt;br /&gt;
COPY ./newapache2conf /etc/apache2/apache2.conf&lt;br /&gt;
&lt;br /&gt;
CMD [&amp;quot;/usr/sbin/apache2&amp;quot;, &amp;quot;-D&amp;quot;, &amp;quot;FOREGROUND&amp;quot;]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
New apache2 conf (see dockerfile for where this goes).&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# This is the main Apache server configuration file.  It contains the&lt;br /&gt;
# configuration directives that give the server its instructions.&lt;br /&gt;
# See http://httpd.apache.org/docs/2.4/ for detailed information about&lt;br /&gt;
# the directives and /usr/share/doc/apache2/README.Debian about Debian specific&lt;br /&gt;
# hints.&lt;br /&gt;
#&lt;br /&gt;
#&lt;br /&gt;
# Summary of how the Apache 2 configuration works in Debian:&lt;br /&gt;
# The Apache 2 web server configuration in Debian is quite different to&lt;br /&gt;
# upstream's suggested way to configure the web server. This is because Debian's&lt;br /&gt;
# default Apache2 installation attempts to make adding and removing modules,&lt;br /&gt;
# virtual hosts, and extra configuration directives as flexible as possible, in&lt;br /&gt;
# order to make automating the changes and administering the server as easy as&lt;br /&gt;
# possible.&lt;br /&gt;
&lt;br /&gt;
# It is split into several files forming the configuration hierarchy outlined&lt;br /&gt;
# below, all located in the /etc/apache2/ directory:&lt;br /&gt;
#&lt;br /&gt;
#	/etc/apache2/&lt;br /&gt;
#	|-- apache2.conf&lt;br /&gt;
#	|	`--  ports.conf&lt;br /&gt;
#	|-- mods-enabled&lt;br /&gt;
#	|	|-- *.load&lt;br /&gt;
#	|	`-- *.conf&lt;br /&gt;
#	|-- conf-enabled&lt;br /&gt;
#	|	`-- *.conf&lt;br /&gt;
# 	`-- sites-enabled&lt;br /&gt;
#	 	`-- *.conf&lt;br /&gt;
#&lt;br /&gt;
#&lt;br /&gt;
# * apache2.conf is the main configuration file (this file). It puts the pieces&lt;br /&gt;
#   together by including all remaining configuration files when starting up the&lt;br /&gt;
#   web server.&lt;br /&gt;
#&lt;br /&gt;
# * ports.conf is always included from the main configuration file. It is&lt;br /&gt;
#   supposed to determine listening ports for incoming connections which can be&lt;br /&gt;
#   customized anytime.&lt;br /&gt;
#&lt;br /&gt;
# * Configuration files in the mods-enabled/, conf-enabled/ and sites-enabled/&lt;br /&gt;
#   directories contain particular configuration snippets which manage modules,&lt;br /&gt;
#   global configuration fragments, or virtual host configurations,&lt;br /&gt;
#   respectively.&lt;br /&gt;
#&lt;br /&gt;
#   They are activated by symlinking available configuration files from their&lt;br /&gt;
#   respective *-available/ counterparts. These should be managed by using our&lt;br /&gt;
#   helpers a2enmod/a2dismod, a2ensite/a2dissite and a2enconf/a2disconf. See&lt;br /&gt;
#   their respective man pages for detailed information.&lt;br /&gt;
#&lt;br /&gt;
# * The binary is called apache2. Due to the use of environment variables, in&lt;br /&gt;
#   the default configuration, apache2 needs to be started/stopped with&lt;br /&gt;
#   /etc/init.d/apache2 or apache2ctl. Calling /usr/bin/apache2 directly will not&lt;br /&gt;
#   work with the default configuration.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# Global configuration&lt;br /&gt;
#&lt;br /&gt;
&lt;br /&gt;
#&lt;br /&gt;
# ServerRoot: The top of the directory tree under which the server's&lt;br /&gt;
# configuration, error, and log files are kept.&lt;br /&gt;
#&lt;br /&gt;
# NOTE!  If you intend to place this on an NFS (or otherwise network)&lt;br /&gt;
# mounted filesystem then please read the Mutex documentation (available&lt;br /&gt;
# at &amp;lt;URL:http://httpd.apache.org/docs/2.4/mod/core.html#mutex&amp;gt;);&lt;br /&gt;
# you will save yourself a lot of trouble.&lt;br /&gt;
#&lt;br /&gt;
# Do NOT add a slash at the end of the directory path.&lt;br /&gt;
#&lt;br /&gt;
#ServerRoot &amp;quot;/etc/apache2&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#&lt;br /&gt;
# The accept serialization lock file MUST BE STORED ON A LOCAL DISK.&lt;br /&gt;
#&lt;br /&gt;
#Mutex file:${APACHE_LOCK_DIR} default&lt;br /&gt;
&lt;br /&gt;
#&lt;br /&gt;
# The directory where shm and other runtime files will be stored.&lt;br /&gt;
#&lt;br /&gt;
&lt;br /&gt;
DefaultRuntimeDir ${APACHE_RUN_DIR}&lt;br /&gt;
&lt;br /&gt;
#&lt;br /&gt;
# PidFile: The file in which the server should record its process&lt;br /&gt;
# identification number when it starts.&lt;br /&gt;
# This needs to be set in /etc/apache2/envvars&lt;br /&gt;
#&lt;br /&gt;
PidFile ${APACHE_PID_FILE}&lt;br /&gt;
&lt;br /&gt;
#&lt;br /&gt;
# Timeout: The number of seconds before receives and sends time out.&lt;br /&gt;
#&lt;br /&gt;
Timeout 300&lt;br /&gt;
&lt;br /&gt;
#&lt;br /&gt;
# KeepAlive: Whether or not to allow persistent connections (more than&lt;br /&gt;
# one request per connection). Set to &amp;quot;Off&amp;quot; to deactivate.&lt;br /&gt;
#&lt;br /&gt;
KeepAlive On&lt;br /&gt;
&lt;br /&gt;
#&lt;br /&gt;
# MaxKeepAliveRequests: The maximum number of requests to allow&lt;br /&gt;
# during a persistent connection. Set to 0 to allow an unlimited amount.&lt;br /&gt;
# We recommend you leave this number high, for maximum performance.&lt;br /&gt;
#&lt;br /&gt;
MaxKeepAliveRequests 100&lt;br /&gt;
&lt;br /&gt;
#&lt;br /&gt;
# KeepAliveTimeout: Number of seconds to wait for the next request from the&lt;br /&gt;
# same client on the same connection.&lt;br /&gt;
#&lt;br /&gt;
KeepAliveTimeout 5&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# These need to be set in /etc/apache2/envvars&lt;br /&gt;
User ${APACHE_RUN_USER}&lt;br /&gt;
Group ${APACHE_RUN_GROUP}&lt;br /&gt;
&lt;br /&gt;
#&lt;br /&gt;
# HostnameLookups: Log the names of clients or just their IP addresses&lt;br /&gt;
# e.g., www.apache.org (on) or 204.62.129.132 (off).&lt;br /&gt;
# The default is off because it'd be overall better for the net if people&lt;br /&gt;
# had to knowingly turn this feature on, since enabling it means that&lt;br /&gt;
# each client request will result in AT LEAST one lookup request to the&lt;br /&gt;
# nameserver.&lt;br /&gt;
#&lt;br /&gt;
HostnameLookups Off&lt;br /&gt;
&lt;br /&gt;
# ErrorLog: The location of the error log file.&lt;br /&gt;
# If you do not specify an ErrorLog directive within a &amp;lt;VirtualHost&amp;gt;&lt;br /&gt;
# container, error messages relating to that virtual host will be&lt;br /&gt;
# logged here.  If you *do* define an error logfile for a &amp;lt;VirtualHost&amp;gt;&lt;br /&gt;
# container, that host's errors will be logged there and not here.&lt;br /&gt;
#&lt;br /&gt;
ErrorLog ${APACHE_LOG_DIR}/error.log&lt;br /&gt;
&lt;br /&gt;
#&lt;br /&gt;
# LogLevel: Control the severity of messages logged to the error_log.&lt;br /&gt;
# Available values: trace8, ..., trace1, debug, info, notice, warn,&lt;br /&gt;
# error, crit, alert, emerg.&lt;br /&gt;
# It is also possible to configure the log level for particular modules, e.g.&lt;br /&gt;
# &amp;quot;LogLevel info ssl:warn&amp;quot;&lt;br /&gt;
#&lt;br /&gt;
LogLevel warn&lt;br /&gt;
&lt;br /&gt;
# Include module configuration:&lt;br /&gt;
IncludeOptional mods-enabled/*.load&lt;br /&gt;
IncludeOptional mods-enabled/*.conf&lt;br /&gt;
&lt;br /&gt;
# Include list of ports to listen on&lt;br /&gt;
Include ports.conf&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# Sets the default security model of the Apache2 HTTPD server. It does&lt;br /&gt;
# not allow access to the root filesystem outside of /usr/share and /var/www.&lt;br /&gt;
# The former is used by web applications packaged in Debian,&lt;br /&gt;
# the latter may be used for local directories served by the web server. If&lt;br /&gt;
# your system is serving content from a sub-directory in /srv you must allow&lt;br /&gt;
# access here, or in any related virtual host.&lt;br /&gt;
&amp;lt;Directory /&amp;gt;&lt;br /&gt;
	Options FollowSymLinks&lt;br /&gt;
	AllowOverride None&lt;br /&gt;
	Require all denied&lt;br /&gt;
&amp;lt;/Directory&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;Directory /usr/share&amp;gt;&lt;br /&gt;
	AllowOverride None&lt;br /&gt;
	Require all granted&lt;br /&gt;
&amp;lt;/Directory&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;Directory /var/www/&amp;gt;&lt;br /&gt;
	Options Indexes FollowSymLinks&lt;br /&gt;
	AllowOverride All&lt;br /&gt;
	Require all granted&lt;br /&gt;
&amp;lt;/Directory&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#&amp;lt;Directory /srv/&amp;gt;&lt;br /&gt;
#	Options Indexes FollowSymLinks&lt;br /&gt;
#	AllowOverride None&lt;br /&gt;
#	Require all granted&lt;br /&gt;
#&amp;lt;/Directory&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# AccessFileName: The name of the file to look for in each directory&lt;br /&gt;
# for additional configuration directives.  See also the AllowOverride&lt;br /&gt;
# directive.&lt;br /&gt;
#&lt;br /&gt;
AccessFileName .htaccess&lt;br /&gt;
&lt;br /&gt;
#&lt;br /&gt;
# The following lines prevent .htaccess and .htpasswd files from being&lt;br /&gt;
# viewed by Web clients.&lt;br /&gt;
#&lt;br /&gt;
&amp;lt;FilesMatch &amp;quot;^\.ht&amp;quot;&amp;gt;&lt;br /&gt;
	Require all denied&lt;br /&gt;
&amp;lt;/FilesMatch&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
#&lt;br /&gt;
# The following directives define some format nicknames for use with&lt;br /&gt;
# a CustomLog directive.&lt;br /&gt;
#&lt;br /&gt;
# These deviate from the Common Log Format definitions in that they use %O&lt;br /&gt;
# (the actual bytes sent including headers) instead of %b (the size of the&lt;br /&gt;
# requested file), because the latter makes it impossible to detect partial&lt;br /&gt;
# requests.&lt;br /&gt;
#&lt;br /&gt;
# Note that the use of %{X-Forwarded-For}i instead of %h is not recommended.&lt;br /&gt;
# Use mod_remoteip instead.&lt;br /&gt;
#&lt;br /&gt;
LogFormat &amp;quot;%v:%p %h %l %u %t \&amp;quot;%r\&amp;quot; %&amp;gt;s %O \&amp;quot;%{Referer}i\&amp;quot; \&amp;quot;%{User-Agent}i\&amp;quot;&amp;quot; vhost_combined&lt;br /&gt;
LogFormat &amp;quot;%h %l %u %t \&amp;quot;%r\&amp;quot; %&amp;gt;s %O \&amp;quot;%{Referer}i\&amp;quot; \&amp;quot;%{User-Agent}i\&amp;quot;&amp;quot; combined&lt;br /&gt;
LogFormat &amp;quot;%h %l %u %t \&amp;quot;%r\&amp;quot; %&amp;gt;s %O&amp;quot; common&lt;br /&gt;
LogFormat &amp;quot;%{Referer}i -&amp;gt; %U&amp;quot; referer&lt;br /&gt;
LogFormat &amp;quot;%{User-agent}i&amp;quot; agent&lt;br /&gt;
&lt;br /&gt;
# Include of directories ignores editors' and dpkg's backup files,&lt;br /&gt;
# see README.Debian for details.&lt;br /&gt;
&lt;br /&gt;
# Include generic snippets of statements&lt;br /&gt;
IncludeOptional conf-enabled/*.conf&lt;br /&gt;
&lt;br /&gt;
# Include the virtual host configurations:&lt;br /&gt;
IncludeOptional sites-enabled/*.conf&lt;br /&gt;
&lt;br /&gt;
# vim: syntax=apache ts=4 sw=4 sts=4 sr noet&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
docker-compose.yml:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
version: '3'&lt;br /&gt;
services:&lt;br /&gt;
  z157:&lt;br /&gt;
    build: ./app/&lt;br /&gt;
    container_name: zencart_157c&lt;br /&gt;
    ports:&lt;br /&gt;
      - &amp;quot;80:80&amp;quot;&lt;br /&gt;
      - &amp;quot;443:443&amp;quot;&lt;br /&gt;
    depends_on:&lt;br /&gt;
      - datab&lt;br /&gt;
  datab:&lt;br /&gt;
    image: mariadb:10.5&lt;br /&gt;
    container_name: db_zencart2&lt;br /&gt;
    volumes:&lt;br /&gt;
      - ./dbdata:/var/lib/mysql&lt;br /&gt;
    environment:&lt;br /&gt;
      MYSQL_ROOT_PASSWORD: ROOTPW&lt;br /&gt;
      MYSQL_USER: user&lt;br /&gt;
      MYSQL_PASSWORD: pass&lt;br /&gt;
      MYSQL_DATABASE: zencart&lt;br /&gt;
    ports:&lt;br /&gt;
      - &amp;quot;3306:3306&amp;quot;&lt;br /&gt;
#volumes:&lt;br /&gt;
#  db-volume:&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Adminguy</name></author>
	</entry>
	<entry>
		<id>http://steakwiki.com/index.php?title=Zencart_docker_compose&amp;diff=988</id>
		<title>Zencart docker compose</title>
		<link rel="alternate" type="text/html" href="http://steakwiki.com/index.php?title=Zencart_docker_compose&amp;diff=988"/>
		<updated>2021-03-16T08:04:35Z</updated>

		<summary type="html">&lt;p&gt;Adminguy: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This was adapted from someone else online. I forget now who. Their example wasn't 100% working.&lt;br /&gt;
&lt;br /&gt;
Here we go:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# zencart on docker&lt;br /&gt;
&lt;br /&gt;
Release 1.57c&lt;br /&gt;
Debian 10&lt;br /&gt;
MariaDB 10.5&lt;br /&gt;
php7.3&lt;br /&gt;
&lt;br /&gt;
5+ hours of work.&lt;br /&gt;
Maybe should've just used a turnkey appliance. Maybe... Maybe not.&lt;br /&gt;
&lt;br /&gt;
# tips&lt;br /&gt;
docker exec -it zencart /bin/bash&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Dockerfile:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
FROM debian:10&lt;br /&gt;
&lt;br /&gt;
RUN apt-get update &amp;amp;&amp;amp; apt-get install -y \&lt;br /&gt;
       libapache2-mod-php7.3 \&lt;br /&gt;
       curl \&lt;br /&gt;
       unzip \&lt;br /&gt;
       apt-utils \&lt;br /&gt;
       zlib1g-dev \&lt;br /&gt;
       libpng-dev \&lt;br /&gt;
       libmcrypt-dev \&lt;br /&gt;
       libzip-dev \&lt;br /&gt;
       zip&lt;br /&gt;
&lt;br /&gt;
RUN apt-get install -y \&lt;br /&gt;
    php7.3-mysql \&lt;br /&gt;
    php-zip \&lt;br /&gt;
    php7.3-gd \&lt;br /&gt;
    php7.3-dev \&lt;br /&gt;
    php7.3-opcache \&lt;br /&gt;
    php7.3-curl \&lt;br /&gt;
    &amp;amp;&amp;amp; pecl install mcrypt-1.0.2&lt;br /&gt;
&lt;br /&gt;
RUN a2enmod rewrite&lt;br /&gt;
RUN a2enmod ssl&lt;br /&gt;
&lt;br /&gt;
ENV APACHE_RUN_USER www-data&lt;br /&gt;
ENV APACHE_RUN_GROUP www-data&lt;br /&gt;
ENV APACHE_LOG_DIR /var/log/apache2&lt;br /&gt;
ENV APACHE_PID_FILE /var/run/apache2.pid&lt;br /&gt;
ENV APACHE_RUN_DIR /var/www/html/&lt;br /&gt;
ENV APACHE_LOCK_DIR /var/lock/apache2&lt;br /&gt;
&lt;br /&gt;
WORKDIR /tmp&lt;br /&gt;
RUN curl -LO https://sourceforge.net/projects/zencart/files/CURRENT%20-%20Zen%20Cart%201.5.x%20Series/zen-cart-v1.5.7c-03052021.zip/download \&lt;br /&gt;
    &amp;amp;&amp;amp; unzip /tmp/download \&lt;br /&gt;
    &amp;amp;&amp;amp; mv /tmp/zen-cart*/* /var/www/html/. \&lt;br /&gt;
    &amp;amp;&amp;amp; cd /var/www/html \&lt;br /&gt;
    &amp;amp;&amp;amp; cp includes/dist-configure.php includes/configure.php \&lt;br /&gt;
    &amp;amp;&amp;amp; cp admin/includes/dist-configure.php admin/includes/configure.php \&lt;br /&gt;
    &amp;amp;&amp;amp; chown -R www-data:www-data /var/www/html&lt;br /&gt;
&lt;br /&gt;
RUN echo '[Date]' &amp;gt; /etc/php/7.3/apache2/conf.d/timezone.ini \&lt;br /&gt;
 &amp;amp;&amp;amp; echo 'date.timezone = &amp;quot;America/New_York&amp;quot;' &amp;gt;&amp;gt; /etc/php/7.3/apache2/conf.d/timezone.ini&lt;br /&gt;
&lt;br /&gt;
RUN ln -s /etc/apache2/sites-available/default-ssl.conf /etc/apache2/sites-enabled/default-ssl.conf&lt;br /&gt;
&lt;br /&gt;
COPY ./newapache2conf /etc/apache2/apache2.conf&lt;br /&gt;
&lt;br /&gt;
CMD [&amp;quot;/usr/sbin/apache2&amp;quot;, &amp;quot;-D&amp;quot;, &amp;quot;FOREGROUND&amp;quot;]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
New apache2 conf (see dockerfile for where this goes).&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# This is the main Apache server configuration file.  It contains the&lt;br /&gt;
# configuration directives that give the server its instructions.&lt;br /&gt;
# See http://httpd.apache.org/docs/2.4/ for detailed information about&lt;br /&gt;
# the directives and /usr/share/doc/apache2/README.Debian about Debian specific&lt;br /&gt;
# hints.&lt;br /&gt;
#&lt;br /&gt;
#&lt;br /&gt;
# Summary of how the Apache 2 configuration works in Debian:&lt;br /&gt;
# The Apache 2 web server configuration in Debian is quite different to&lt;br /&gt;
# upstream's suggested way to configure the web server. This is because Debian's&lt;br /&gt;
# default Apache2 installation attempts to make adding and removing modules,&lt;br /&gt;
# virtual hosts, and extra configuration directives as flexible as possible, in&lt;br /&gt;
# order to make automating the changes and administering the server as easy as&lt;br /&gt;
# possible.&lt;br /&gt;
&lt;br /&gt;
# It is split into several files forming the configuration hierarchy outlined&lt;br /&gt;
# below, all located in the /etc/apache2/ directory:&lt;br /&gt;
#&lt;br /&gt;
#	/etc/apache2/&lt;br /&gt;
#	|-- apache2.conf&lt;br /&gt;
#	|	`--  ports.conf&lt;br /&gt;
#	|-- mods-enabled&lt;br /&gt;
#	|	|-- *.load&lt;br /&gt;
#	|	`-- *.conf&lt;br /&gt;
#	|-- conf-enabled&lt;br /&gt;
#	|	`-- *.conf&lt;br /&gt;
# 	`-- sites-enabled&lt;br /&gt;
#	 	`-- *.conf&lt;br /&gt;
#&lt;br /&gt;
#&lt;br /&gt;
# * apache2.conf is the main configuration file (this file). It puts the pieces&lt;br /&gt;
#   together by including all remaining configuration files when starting up the&lt;br /&gt;
#   web server.&lt;br /&gt;
#&lt;br /&gt;
# * ports.conf is always included from the main configuration file. It is&lt;br /&gt;
#   supposed to determine listening ports for incoming connections which can be&lt;br /&gt;
#   customized anytime.&lt;br /&gt;
#&lt;br /&gt;
# * Configuration files in the mods-enabled/, conf-enabled/ and sites-enabled/&lt;br /&gt;
#   directories contain particular configuration snippets which manage modules,&lt;br /&gt;
#   global configuration fragments, or virtual host configurations,&lt;br /&gt;
#   respectively.&lt;br /&gt;
#&lt;br /&gt;
#   They are activated by symlinking available configuration files from their&lt;br /&gt;
#   respective *-available/ counterparts. These should be managed by using our&lt;br /&gt;
#   helpers a2enmod/a2dismod, a2ensite/a2dissite and a2enconf/a2disconf. See&lt;br /&gt;
#   their respective man pages for detailed information.&lt;br /&gt;
#&lt;br /&gt;
# * The binary is called apache2. Due to the use of environment variables, in&lt;br /&gt;
#   the default configuration, apache2 needs to be started/stopped with&lt;br /&gt;
#   /etc/init.d/apache2 or apache2ctl. Calling /usr/bin/apache2 directly will not&lt;br /&gt;
#   work with the default configuration.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# Global configuration&lt;br /&gt;
#&lt;br /&gt;
&lt;br /&gt;
#&lt;br /&gt;
# ServerRoot: The top of the directory tree under which the server's&lt;br /&gt;
# configuration, error, and log files are kept.&lt;br /&gt;
#&lt;br /&gt;
# NOTE!  If you intend to place this on an NFS (or otherwise network)&lt;br /&gt;
# mounted filesystem then please read the Mutex documentation (available&lt;br /&gt;
# at &amp;lt;URL:http://httpd.apache.org/docs/2.4/mod/core.html#mutex&amp;gt;);&lt;br /&gt;
# you will save yourself a lot of trouble.&lt;br /&gt;
#&lt;br /&gt;
# Do NOT add a slash at the end of the directory path.&lt;br /&gt;
#&lt;br /&gt;
#ServerRoot &amp;quot;/etc/apache2&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#&lt;br /&gt;
# The accept serialization lock file MUST BE STORED ON A LOCAL DISK.&lt;br /&gt;
#&lt;br /&gt;
#Mutex file:${APACHE_LOCK_DIR} default&lt;br /&gt;
&lt;br /&gt;
#&lt;br /&gt;
# The directory where shm and other runtime files will be stored.&lt;br /&gt;
#&lt;br /&gt;
&lt;br /&gt;
DefaultRuntimeDir ${APACHE_RUN_DIR}&lt;br /&gt;
&lt;br /&gt;
#&lt;br /&gt;
# PidFile: The file in which the server should record its process&lt;br /&gt;
# identification number when it starts.&lt;br /&gt;
# This needs to be set in /etc/apache2/envvars&lt;br /&gt;
#&lt;br /&gt;
PidFile ${APACHE_PID_FILE}&lt;br /&gt;
&lt;br /&gt;
#&lt;br /&gt;
# Timeout: The number of seconds before receives and sends time out.&lt;br /&gt;
#&lt;br /&gt;
Timeout 300&lt;br /&gt;
&lt;br /&gt;
#&lt;br /&gt;
# KeepAlive: Whether or not to allow persistent connections (more than&lt;br /&gt;
# one request per connection). Set to &amp;quot;Off&amp;quot; to deactivate.&lt;br /&gt;
#&lt;br /&gt;
KeepAlive On&lt;br /&gt;
&lt;br /&gt;
#&lt;br /&gt;
# MaxKeepAliveRequests: The maximum number of requests to allow&lt;br /&gt;
# during a persistent connection. Set to 0 to allow an unlimited amount.&lt;br /&gt;
# We recommend you leave this number high, for maximum performance.&lt;br /&gt;
#&lt;br /&gt;
MaxKeepAliveRequests 100&lt;br /&gt;
&lt;br /&gt;
#&lt;br /&gt;
# KeepAliveTimeout: Number of seconds to wait for the next request from the&lt;br /&gt;
# same client on the same connection.&lt;br /&gt;
#&lt;br /&gt;
KeepAliveTimeout 5&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# These need to be set in /etc/apache2/envvars&lt;br /&gt;
User ${APACHE_RUN_USER}&lt;br /&gt;
Group ${APACHE_RUN_GROUP}&lt;br /&gt;
&lt;br /&gt;
#&lt;br /&gt;
# HostnameLookups: Log the names of clients or just their IP addresses&lt;br /&gt;
# e.g., www.apache.org (on) or 204.62.129.132 (off).&lt;br /&gt;
# The default is off because it'd be overall better for the net if people&lt;br /&gt;
# had to knowingly turn this feature on, since enabling it means that&lt;br /&gt;
# each client request will result in AT LEAST one lookup request to the&lt;br /&gt;
# nameserver.&lt;br /&gt;
#&lt;br /&gt;
HostnameLookups Off&lt;br /&gt;
&lt;br /&gt;
# ErrorLog: The location of the error log file.&lt;br /&gt;
# If you do not specify an ErrorLog directive within a &amp;lt;VirtualHost&amp;gt;&lt;br /&gt;
# container, error messages relating to that virtual host will be&lt;br /&gt;
# logged here.  If you *do* define an error logfile for a &amp;lt;VirtualHost&amp;gt;&lt;br /&gt;
# container, that host's errors will be logged there and not here.&lt;br /&gt;
#&lt;br /&gt;
ErrorLog ${APACHE_LOG_DIR}/error.log&lt;br /&gt;
&lt;br /&gt;
#&lt;br /&gt;
# LogLevel: Control the severity of messages logged to the error_log.&lt;br /&gt;
# Available values: trace8, ..., trace1, debug, info, notice, warn,&lt;br /&gt;
# error, crit, alert, emerg.&lt;br /&gt;
# It is also possible to configure the log level for particular modules, e.g.&lt;br /&gt;
# &amp;quot;LogLevel info ssl:warn&amp;quot;&lt;br /&gt;
#&lt;br /&gt;
LogLevel warn&lt;br /&gt;
&lt;br /&gt;
# Include module configuration:&lt;br /&gt;
IncludeOptional mods-enabled/*.load&lt;br /&gt;
IncludeOptional mods-enabled/*.conf&lt;br /&gt;
&lt;br /&gt;
# Include list of ports to listen on&lt;br /&gt;
Include ports.conf&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# Sets the default security model of the Apache2 HTTPD server. It does&lt;br /&gt;
# not allow access to the root filesystem outside of /usr/share and /var/www.&lt;br /&gt;
# The former is used by web applications packaged in Debian,&lt;br /&gt;
# the latter may be used for local directories served by the web server. If&lt;br /&gt;
# your system is serving content from a sub-directory in /srv you must allow&lt;br /&gt;
# access here, or in any related virtual host.&lt;br /&gt;
&amp;lt;Directory /&amp;gt;&lt;br /&gt;
	Options FollowSymLinks&lt;br /&gt;
	AllowOverride None&lt;br /&gt;
	Require all denied&lt;br /&gt;
&amp;lt;/Directory&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;Directory /usr/share&amp;gt;&lt;br /&gt;
	AllowOverride None&lt;br /&gt;
	Require all granted&lt;br /&gt;
&amp;lt;/Directory&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;Directory /var/www/&amp;gt;&lt;br /&gt;
	Options Indexes FollowSymLinks&lt;br /&gt;
	AllowOverride All&lt;br /&gt;
	Require all granted&lt;br /&gt;
&amp;lt;/Directory&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#&amp;lt;Directory /srv/&amp;gt;&lt;br /&gt;
#	Options Indexes FollowSymLinks&lt;br /&gt;
#	AllowOverride None&lt;br /&gt;
#	Require all granted&lt;br /&gt;
#&amp;lt;/Directory&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# AccessFileName: The name of the file to look for in each directory&lt;br /&gt;
# for additional configuration directives.  See also the AllowOverride&lt;br /&gt;
# directive.&lt;br /&gt;
#&lt;br /&gt;
AccessFileName .htaccess&lt;br /&gt;
&lt;br /&gt;
#&lt;br /&gt;
# The following lines prevent .htaccess and .htpasswd files from being&lt;br /&gt;
# viewed by Web clients.&lt;br /&gt;
#&lt;br /&gt;
&amp;lt;FilesMatch &amp;quot;^\.ht&amp;quot;&amp;gt;&lt;br /&gt;
	Require all denied&lt;br /&gt;
&amp;lt;/FilesMatch&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
#&lt;br /&gt;
# The following directives define some format nicknames for use with&lt;br /&gt;
# a CustomLog directive.&lt;br /&gt;
#&lt;br /&gt;
# These deviate from the Common Log Format definitions in that they use %O&lt;br /&gt;
# (the actual bytes sent including headers) instead of %b (the size of the&lt;br /&gt;
# requested file), because the latter makes it impossible to detect partial&lt;br /&gt;
# requests.&lt;br /&gt;
#&lt;br /&gt;
# Note that the use of %{X-Forwarded-For}i instead of %h is not recommended.&lt;br /&gt;
# Use mod_remoteip instead.&lt;br /&gt;
#&lt;br /&gt;
LogFormat &amp;quot;%v:%p %h %l %u %t \&amp;quot;%r\&amp;quot; %&amp;gt;s %O \&amp;quot;%{Referer}i\&amp;quot; \&amp;quot;%{User-Agent}i\&amp;quot;&amp;quot; vhost_combined&lt;br /&gt;
LogFormat &amp;quot;%h %l %u %t \&amp;quot;%r\&amp;quot; %&amp;gt;s %O \&amp;quot;%{Referer}i\&amp;quot; \&amp;quot;%{User-Agent}i\&amp;quot;&amp;quot; combined&lt;br /&gt;
LogFormat &amp;quot;%h %l %u %t \&amp;quot;%r\&amp;quot; %&amp;gt;s %O&amp;quot; common&lt;br /&gt;
LogFormat &amp;quot;%{Referer}i -&amp;gt; %U&amp;quot; referer&lt;br /&gt;
LogFormat &amp;quot;%{User-agent}i&amp;quot; agent&lt;br /&gt;
&lt;br /&gt;
# Include of directories ignores editors' and dpkg's backup files,&lt;br /&gt;
# see README.Debian for details.&lt;br /&gt;
&lt;br /&gt;
# Include generic snippets of statements&lt;br /&gt;
IncludeOptional conf-enabled/*.conf&lt;br /&gt;
&lt;br /&gt;
# Include the virtual host configurations:&lt;br /&gt;
IncludeOptional sites-enabled/*.conf&lt;br /&gt;
&lt;br /&gt;
# vim: syntax=apache ts=4 sw=4 sts=4 sr noet&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
docker-compose.yml:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
version: '3'&lt;br /&gt;
services:&lt;br /&gt;
  z157:&lt;br /&gt;
    build: ./app/&lt;br /&gt;
    container_name: zencart_157c&lt;br /&gt;
    ports:&lt;br /&gt;
      - &amp;quot;80:80&amp;quot;&lt;br /&gt;
      - &amp;quot;443:443&amp;quot;&lt;br /&gt;
    depends_on:&lt;br /&gt;
      - datab&lt;br /&gt;
  datab:&lt;br /&gt;
    image: mariadb:10.5&lt;br /&gt;
    container_name: db_zencart2&lt;br /&gt;
    volumes:&lt;br /&gt;
      - ./dbdata:/var/lib/mysql&lt;br /&gt;
    environment:&lt;br /&gt;
      MYSQL_ROOT_PASSWORD: ROOTPW&lt;br /&gt;
      MYSQL_USER: user&lt;br /&gt;
      MYSQL_PASSWORD: pass&lt;br /&gt;
      MYSQL_DATABASE: zencart&lt;br /&gt;
    ports:&lt;br /&gt;
      - &amp;quot;3306:3306&amp;quot;&lt;br /&gt;
#volumes:&lt;br /&gt;
#  db-volume:&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Adminguy</name></author>
	</entry>
	<entry>
		<id>http://steakwiki.com/index.php?title=Zencart_docker_compose&amp;diff=987</id>
		<title>Zencart docker compose</title>
		<link rel="alternate" type="text/html" href="http://steakwiki.com/index.php?title=Zencart_docker_compose&amp;diff=987"/>
		<updated>2021-03-16T08:02:47Z</updated>

		<summary type="html">&lt;p&gt;Adminguy: Created page with &amp;quot;This was adapted from someone else online. I forget now who. Their example wasn't 100% working.  Here we go: &amp;lt;pre&amp;gt; # zencart on docker  Release 1.57c Debian 10 MariaDB 10.5 ph...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This was adapted from someone else online. I forget now who. Their example wasn't 100% working.&lt;br /&gt;
&lt;br /&gt;
Here we go:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# zencart on docker&lt;br /&gt;
&lt;br /&gt;
Release 1.57c&lt;br /&gt;
Debian 10&lt;br /&gt;
MariaDB 10.5&lt;br /&gt;
php7.3&lt;br /&gt;
&lt;br /&gt;
5+ hours of work.&lt;br /&gt;
Maybe should've just used a turnkey appliance. Maybe... Maybe not.&lt;br /&gt;
&lt;br /&gt;
# tips&lt;br /&gt;
docker exec -it zencart /bin/bash&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Adminguy</name></author>
	</entry>
	<entry>
		<id>http://steakwiki.com/index.php?title=Docker&amp;diff=986</id>
		<title>Docker</title>
		<link rel="alternate" type="text/html" href="http://steakwiki.com/index.php?title=Docker&amp;diff=986"/>
		<updated>2021-03-16T08:01:24Z</updated>

		<summary type="html">&lt;p&gt;Adminguy: /* See Also */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;small&amp;gt;Docker is a type of virtualization for Gnu\Linux that allows programs to run and share similar resources, without having a full OS for each image, but while still isolating each 'vm'.&lt;br /&gt;
&lt;br /&gt;
==General Tips==&lt;br /&gt;
It helps to read a book, and then keep it as a Reference. Here Using Docker By Adrian Mouat is a decent book. In fact, you should be reading books on any subject that interests you. Physical paper books, too.&lt;br /&gt;
&lt;br /&gt;
Docker is x86_64. ARM has a separate build. There is no i386.&lt;br /&gt;
&lt;br /&gt;
You will want 'some' RAM. I had 1GB on a P4 machine, and that was not enough. 4GB was enough. &lt;br /&gt;
&lt;br /&gt;
You should always use docker compose. Docker is possible to run on the command line, but with a compose file, you can write everything down in a much simpler fashion. Use compose. It's a separate install, currently. Install it. ''Seriously, just ignore the docker command lines. I consider them useless. More of a red herring for rookies.''&lt;br /&gt;
&lt;br /&gt;
===ARM is SOL===&lt;br /&gt;
I tried to use Docker on ARM, and while you might be able to install docker, you will find that images for your applications may not be there. e.g. you will find Nginx, but you won't find Gitlab. This means that docker is pretty much x86-64 only.&lt;br /&gt;
&lt;br /&gt;
==Docker Commands==&lt;br /&gt;
Here are commands you need to know. Just the necessary ones.&lt;br /&gt;
{{cmd| docker-compose up -d}} &lt;br /&gt;
 &lt;br /&gt;
Starts the containers in the docker compose file, if they aren't already started. the -d detaches from the stdout logging. You don't need to use stdout logging, you can use docker logs, but its there if you want it.&lt;br /&gt;
 {{cmd| docker ps }}&lt;br /&gt;
Lists containers running. If one fails to start, you'll see it missing from here&lt;br /&gt;
 {{cmd|docker logs &amp;lt;containername&amp;gt; }}&lt;br /&gt;
Gives you some logging output from the container. Often enough to troubleshoot. (also see tips below).&lt;br /&gt;
 {{cmd|docker exec -it &amp;lt;containername&amp;gt; /bin/bash}}&lt;br /&gt;
This will get you in a shell in the docker container. From here you can do what you need to. Most are debian, and need apt-get install less nano or whatever program you are missing. Ping is missing from possibly all containers, so if you want to test via ping, you'll have to apt-get it.&lt;br /&gt;
 {{cmd|docker-compose restart }}&lt;br /&gt;
This will restart all containers. However, I don't recommend it. Initting containers can get corrupted this way, and also its much easier to restart a single faulty container via...&lt;br /&gt;
 {{cmd|docker restart &amp;lt;containername&amp;gt; }}&lt;br /&gt;
This will restart one single container.&lt;br /&gt;
 {{cmd|docker cp &amp;lt;containername&amp;gt;:/dir/to/file dest }}&lt;br /&gt;
You can copy files from local machine to docker, or vice versa with this. Extremely useful.&lt;br /&gt;
&lt;br /&gt;
===Deleting Containers===&lt;br /&gt;
Less often, you might want to know &lt;br /&gt;
{{cmd|&lt;br /&gt;
 #!/bin/bash&lt;br /&gt;
 docker rm $(docker ps -a -q)&lt;br /&gt;
 docker rmi $(docker images -q) --force}}&lt;br /&gt;
&lt;br /&gt;
This starts over from scratch. This is how easy it is to reboot a docker from square one.  note: below command (rmi), only needed if you want to remove base images. Needed when updating a stable. Not needed when changing other parameters not related to base image. Also, this deletes all containers, which maybe you don't want to do, if you either A) only want to delete certain images you are testing B) have some containers with custom changes saved, and not backed up elsewhere.&lt;br /&gt;
&lt;br /&gt;
===Updating===&lt;br /&gt;
 docker images&lt;br /&gt;
 (shows out of date image)&lt;br /&gt;
 docker pull mysql&lt;br /&gt;
 (downloads new image)&lt;br /&gt;
 docker images&lt;br /&gt;
 (shows two versions of mysql. old and new)&lt;br /&gt;
 docker stop some_container_name&lt;br /&gt;
 docker rmi -f cjklfs23404&lt;br /&gt;
 (where cjklfs23404 is the old container alias under docker images)&lt;br /&gt;
 docker-compose up -d mysql&lt;br /&gt;
&lt;br /&gt;
====Containers don't all Restart?!====&lt;br /&gt;
Make sure to have in your docker compose for each container a '''restart:always'''&lt;br /&gt;
Otherwise, a container won't necessarily start when docker is restarted.&lt;br /&gt;
&lt;br /&gt;
===Search for images===&lt;br /&gt;
 docker search &amp;lt;imagename&amp;gt;&lt;br /&gt;
====Search for Versions of an image====&lt;br /&gt;
What if you want to see what versions are available for a given image? Say you want php, but don't know which to get. hub.docker.com is broken. Requires js, slow, and bad. You can't get a list of images on it easily. &lt;br /&gt;
&lt;br /&gt;
Solution:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
#https://stackoverflow.com/questions/28320134/how-can-i-list-all-tags-for-a-docker-image-on-a-remote-registry&lt;br /&gt;
#$1 means&lt;br /&gt;
#first parameter you pass to this script will be searched&lt;br /&gt;
#e.g. working: debian&lt;br /&gt;
#note: some have multiple layers&lt;br /&gt;
#e.g. gitea/gitea is literally entered as $1 == gitea/gitea  (teste, working)&lt;br /&gt;
# while debian is just debian. so be aware.&lt;br /&gt;
&lt;br /&gt;
wget -q https://registry.hub.docker.com/v1/repositories/$1/tags -O -  \&lt;br /&gt;
| sed -e 's/[][]//g' -e 's/&amp;quot;//g' -e 's/ //g' | tr '}' '\n'  | awk -F: '{print $3}'&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Ref: https://stackoverflow.com/questions/54418542/dockerhub-listing-all-available-versions-of-a-given-image&lt;br /&gt;
&lt;br /&gt;
https://stackoverflow.com/questions/28320134/how-can-i-list-all-tags-for-a-docker-image-on-a-remote-registry&lt;br /&gt;
&lt;br /&gt;
===Save Changes to Docker Image===&lt;br /&gt;
 docker commit&lt;br /&gt;
See official documentation.&lt;br /&gt;
&lt;br /&gt;
==Dockerfile==&lt;br /&gt;
Dockerfiles and compose are slightly confusing. Sometimes you see images run an entrypoint script, sometimes not. In any case, Dockerfiles are fundamental to reproducible builds.&lt;br /&gt;
&lt;br /&gt;
Basic usage is:&lt;br /&gt;
* Docker-compose builds container from dockerfile (say you start with alpine, and install some programs)&lt;br /&gt;
* that container you built is used from thence on. &lt;br /&gt;
* if you want to change dockerfile, make changes and you must call docker-compose up --build otherwise, it will use the old container&lt;br /&gt;
&lt;br /&gt;
For a basic apache server, you might call the following in a cmd at the end of the dockerfile:&lt;br /&gt;
 CMD [&amp;quot;/usr/sbin/apache2&amp;quot;, &amp;quot;-D&amp;quot;, &amp;quot;FOREGROUND&amp;quot;]&lt;br /&gt;
When in doubt, work off of existing examples.&lt;br /&gt;
&lt;br /&gt;
==Volumes==&lt;br /&gt;
Volumes can be handled at least two ways. The simplest is to store files in a local directory which is then mapped to the remote drive.&lt;br /&gt;
&lt;br /&gt;
e.g. docker-compose:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  nginx:&lt;br /&gt;
    image: nginx:####&lt;br /&gt;
    container_name: mynginxserver&lt;br /&gt;
    volumes:&lt;br /&gt;
      - ./nginx.conf:/etc/nginx/nginx.conf&lt;br /&gt;
      - /etc/letsencrypt/:/etc/letsencrypt/&lt;br /&gt;
      - ./local_dir/:/var/www/html/&lt;br /&gt;
      - ./local_logs/:/var/log/nginx/&lt;br /&gt;
    ports:&lt;br /&gt;
      - 80:80&lt;br /&gt;
      - 443:443&lt;br /&gt;
    restart: always&lt;br /&gt;
    logging:&lt;br /&gt;
      driver: &amp;quot;json-file&amp;quot;&lt;br /&gt;
      options:&lt;br /&gt;
        max-size: &amp;quot;200k&amp;quot;&lt;br /&gt;
        max-file: &amp;quot;10&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Here, in the local dir where docker-compose is run, the ./local_dir/ or ./local_logs will store the containers html or logs respectively. Simple. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
However, if you just have a volume, without a local directory, then it will save in /var/ somewhere (unintuitive... bad).&lt;br /&gt;
e.g. from Dolibarr:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
The Dolibarr installation and all data beyond what lives in the database&lt;br /&gt;
 (file uploads, etc) are stored in the unnamed docker volume volume&lt;br /&gt;
/var/www/html and /var/www/documents. The docker daemon will store&lt;br /&gt;
 that data within the docker directory /var/lib/docker/volumes/....&lt;br /&gt;
That means your data is saved even if the container crashes, is stopped&lt;br /&gt;
or deleted.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Specific Tips==&lt;br /&gt;
===YAML is space sensitive===&lt;br /&gt;
When you edit the .yml file for docker-compose, you have to hit spaces in a certain pattern (tabs not allowed). This is absurd, but just be aware. The errors are cryptic, and its often just because the spacing doesn't stick to what it expects.&lt;br /&gt;
===If you restart a containers namesake process, it will probably restart / reset the container===&lt;br /&gt;
So if you are troubleshooting an apache container, you edit some files, then /etc/init.d/apache2 restart, uh oh... You just undid all the edits you made, if they aren't in a permanent volume. You can shell in, make edits, and then exit the shell, but a service restart often resets the container.&lt;br /&gt;
===Consider a single reverse proxy, to handle multiple websites===&lt;br /&gt;
There are many ways to do this. I use an nginx proxy from scratch. You can also use some containers that are built for this purpose (I personally think it's bloated but a lot of people use Jason Wilder's proxy)&lt;br /&gt;
https://web.archive.org/web/https://github.com/jwilder/nginx-proxy - A lot of people swear by this, but I think it's straying too far to the high level.&lt;br /&gt;
===If you use a single reverse proxy, Lets Encrypt can be done easy===&lt;br /&gt;
In this case scenario you would have certbot on the host and a local volume that the proxy has access to which is the webroot of the Lets Encrypt scripts. The nginx proxy entry look something like this:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
location ^~ /.well-known {&lt;br /&gt;
     alias /var/www/html/.well-known/;&lt;br /&gt;
      autoindex on;&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
And this is put in every server declaration of nginx.conf. Real simple, real easy. The docker compose of the nginx proxy is something like:&lt;br /&gt;
&lt;br /&gt;
{{cat|docker-compose.yml|&lt;br /&gt;
nginx:&lt;br /&gt;
    image: nginx:latest&lt;br /&gt;
    container_name: custom_name_for_my_proxy&lt;br /&gt;
    volumes:&lt;br /&gt;
      - ./nginx.conf:/etc/nginx/nginx.conf&lt;br /&gt;
      - /etc/letsencrypt/:/etc/letsencrypt/&lt;br /&gt;
      - ./webroot/:/var/www/html/&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
The volumes section is extremely simple, don't be scared. There are two entries. Local and remote. You specify what folder will be the local directory which will be cloned to the host at the remote path you specify. So, the host runs certbot at /etc/letsencrypt, and this folder is cloned to the nginx proxy container, at the same location. Finally, webroot must be set in certbot, but it prompts you for this. And if you forget or get it wrong, it can be configured somewhere in /etc/letsencrypt. it's a one liner text entry).&lt;br /&gt;
&lt;br /&gt;
===Give every Container a Containername===&lt;br /&gt;
This makes it easier to refer to them later. All you need to do in the compose file is include container\_name: something. Much better than the gibberish they give these names if you don't include it.&lt;br /&gt;
===Beware of Interrupting Initting Containers===&lt;br /&gt;
When you first build a container, it might take 30-60 or more seconds to do whatever it needs to do. If, before then, you restart it... It may get corrupted. This has happened to me more than once. When you are testing a new container, and it doesn't seem to work for some inexplicable reason, create a container with a new name (it will create a new one), or delete the first one, and start it again.&lt;br /&gt;
===Put Apache or Program logs from the Container in a volume that is locally accessible===&lt;br /&gt;
This means you want a volume something like ./containerA\_files/logs:/var/www/log/apache2/ so that you can monitor the logs from your host machine easily. docker logs doesn't have everything.&lt;br /&gt;
===Only Restart Containers you need to Restart===&lt;br /&gt;
You can restart everything with docker-compose restart, but it's faster, and less prone to break initting containers, if you docker restart containername. Do the latter.&lt;br /&gt;
===Volumes Mounting Over Existing Directories===&lt;br /&gt;
As discussed here: https://web.archive.org/web/https://github.com/moby/moby/issues/4361, if you add a volume to an existing container, it will seem to delete the folder's contents. I've seen mixed behaviour with this. Sometimes it deletes it even if you start a new container with the folder... Other times it has not. In any case, just docker cp the files to the folder, then add the volume mount. This may not be the most graceful solution for upgrades, but it will work. Best practices would be here (See: dbxt commented Dec 14, 2014): https://web.archive.org/web/https://github.com/docker-library/wordpress/issues/10&lt;br /&gt;
===If you edit a docker-compose file you must restart the container with Docker-compose===&lt;br /&gt;
If you make a change in docker compose, you must docker stop service, then docker-compose up -d service. Otherwise the changes will not take effect. The mistake here, would be thinking that you could just docker stop service, then docker start service... That doesn't work.&lt;br /&gt;
===Keep verbose logging off your HDD with RAM only logging===&lt;br /&gt;
If you have e.g. apache/nginx write to your HDD with every website visit, it will quickly wear out your HDD (esp. SSD). Put verbose logging in the RAM only with a tmpfs mount. https://docs.docker.com/storage/tmpfs/&lt;br /&gt;
&lt;br /&gt;
e.g. (ref: https://stackoverflow.com/questions/41902930/docker-compose-tmpfs-not-working)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
services:&lt;br /&gt;
  ubuntu:&lt;br /&gt;
    image: ubuntu&lt;br /&gt;
    command: &amp;quot;bash -c 'mount'&amp;quot;&lt;br /&gt;
    volumes:&lt;br /&gt;
      - cache_vol:/var/cache&lt;br /&gt;
      - run_vol:/run&lt;br /&gt;
&lt;br /&gt;
volumes:&lt;br /&gt;
  run_vol:&lt;br /&gt;
    driver_opts:&lt;br /&gt;
      type: tmpfs&lt;br /&gt;
      device: tmpfs&lt;br /&gt;
  cache_vol:&lt;br /&gt;
    driver_opts:&lt;br /&gt;
      type: tmpfs&lt;br /&gt;
      device: tmpfs&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This also allows you to share the tmpfs mounts if needed.&lt;br /&gt;
&lt;br /&gt;
Access it from host via:&lt;br /&gt;
 docker exec -it nginx_server tail -F /run/shm/access.log&lt;br /&gt;
Note that you might think you can do&lt;br /&gt;
 docker container run my_nginx_server tail -F /run/shm/access.log&lt;br /&gt;
But that will only work on container base images, not running containers. To 'execute' a command on a running or existing container, the command you want is exec. (Also used to interactively start bash shell above)&lt;br /&gt;
&lt;br /&gt;
EDIT: Use with discretion. Active data in RAM may use power.&lt;br /&gt;
&lt;br /&gt;
===Mysql Backup / Restore===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# Backup&lt;br /&gt;
docker exec CONTAINER /usr/bin/mysqldump -u root --password=root DATABASE &amp;gt; backup.sql&lt;br /&gt;
&lt;br /&gt;
# Restore&lt;br /&gt;
cat backup.sql | docker exec -i CONTAINER /usr/bin/mysql -u root --password=root DATABASE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
ref: https://gist.github.com/spalladino/6d981f7b33f6e0afe6bb&lt;br /&gt;
May not need to do this, if you keep the DB (ibdata files) in a local directory/volume via docker-compose.yml&lt;br /&gt;
e.g.&lt;br /&gt;
 mydb:&lt;br /&gt;
    image: mysql:9999&lt;br /&gt;
    volumes:&lt;br /&gt;
       - ./db_files:/var/lib/mysql&lt;br /&gt;
    restart: always&lt;br /&gt;
&lt;br /&gt;
===Limit docker logs===&lt;br /&gt;
Docker will keep lots of logs if you don't manage it.&lt;br /&gt;
https://github.com/docker/compose/issues/1083&lt;br /&gt;
https://docs.docker.com/compose/compose-file/#logging&lt;br /&gt;
https://stackoverflow.com/questions/31829587/docker-container-logs-taking-all-my-disk-space&lt;br /&gt;
view (all) logs with &lt;br /&gt;
 docker-compose logs&lt;br /&gt;
To limit a service's logs in docker-compose do the following:&lt;br /&gt;
* find a containers/services entry&lt;br /&gt;
* append to the end (watch the white space &amp;amp; no tabs)&lt;br /&gt;
     logging:&lt;br /&gt;
       driver: &amp;quot;json-file&amp;quot;&lt;br /&gt;
       options:&lt;br /&gt;
         max-size: &amp;quot;200k&amp;quot;&lt;br /&gt;
         max-file: &amp;quot;10&amp;quot;&lt;br /&gt;
The rule with logs, is nothing - unless you need it. Then everything. Any unnecessary logging is taxing the CPU / HDD.&lt;br /&gt;
Which leads me to...&lt;br /&gt;
&lt;br /&gt;
===view details about container===&lt;br /&gt;
To view paths, configuration settings, etc...&lt;br /&gt;
See&lt;br /&gt;
 docker inspect &amp;lt;name or id&amp;gt;&lt;br /&gt;
It's easier to grep these. the search in less wasn't working for me to find .LogPath for example.&lt;br /&gt;
 docker inspect mycontainer | grep log&lt;br /&gt;
Will show where the log files are located.&lt;br /&gt;
&lt;br /&gt;
===Installing Docker-compose from pip or github binary not Debian===&lt;br /&gt;
Subject. See official docker documentation which states the URL of&lt;br /&gt;
github.com/docker/compose/releases or pip.&lt;br /&gt;
&lt;br /&gt;
Pip is probably better.&lt;br /&gt;
 apt-get install python3-pip &lt;br /&gt;
 pip3 install docker-compose&lt;br /&gt;
&lt;br /&gt;
==Troubleshooting==&lt;br /&gt;
===Cannot start container: [0] Id already in use #20570===&lt;br /&gt;
* https://github.com/moby/moby/issues/20570&lt;br /&gt;
After update, unable to start container. Solution was found to be:&lt;br /&gt;
 docker-compose down -v then docker-compose up -d&lt;br /&gt;
Container was viewable with&lt;br /&gt;
 docker ps -a (not just docker ps)&lt;br /&gt;
==Poor Design==&lt;br /&gt;
===Creating a docker-compose with a stable or latest tag===&lt;br /&gt;
If you make a docker-compose file, you should link it to a marked version. You can later edit it, to use stable or latest, but one of the strengths of Docker is version control. If you create a docker-compose, always test on a specific version, should you need to roll back in the future. Otherwise, your scripts will fail in 2-20-200 years when the conf files are not supported anymore.&lt;br /&gt;
&lt;br /&gt;
e.g. https://github.com/nucreativa/frontaccounting-docker   (6th commit)&lt;br /&gt;
Here, the nginx config is no longer supported in vhosts, it must be in server_blocks. This would've been avoided by denoting a fixed nginx release instead of tag:latest.&lt;br /&gt;
&lt;br /&gt;
==See Also==&lt;br /&gt;
&lt;br /&gt;
* [[samba_docker_by_dlandon]]&lt;br /&gt;
* [[zencart_docker_compose]]&lt;br /&gt;
&lt;br /&gt;
==External Links==&lt;br /&gt;
* https://github.com/LeCoupa/awesome-cheatsheets/blob/master/tools/docker.sh Information dense cheatsheet (unfortunately github)&lt;br /&gt;
* https://gist.github.com/spalladino/6d981f7b33f6e0afe6bb A million idiots type &amp;quot;thanks&amp;quot;. Also the source for the mysql backup command.&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
{{GNU\Linux}}&lt;/div&gt;</summary>
		<author><name>Adminguy</name></author>
	</entry>
	<entry>
		<id>http://steakwiki.com/index.php?title=Irssi&amp;diff=985</id>
		<title>Irssi</title>
		<link rel="alternate" type="text/html" href="http://steakwiki.com/index.php?title=Irssi&amp;diff=985"/>
		<updated>2021-03-15T10:51:22Z</updated>

		<summary type="html">&lt;p&gt;Adminguy: /* Other */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Because discord and slack are proprietary.&lt;br /&gt;
&lt;br /&gt;
I've tried a few times to get into irssi, but realized the only way I'd be able to use it is with a long term running VPS, and documenting my steps here.&lt;br /&gt;
&lt;br /&gt;
==Usage==&lt;br /&gt;
Login to VPS. Start tmux with &lt;br /&gt;
 tmux new -s irssi irssi&lt;br /&gt;
If you later logout, you can re attach with:&lt;br /&gt;
 tmux attach -t irssi&lt;br /&gt;
or alternatively, if you only have one tmux window open:&lt;br /&gt;
 tmux attach&lt;br /&gt;
NOTE: You can close the window (I have a kill shortcut on F12) or ctrl-b d&lt;br /&gt;
to detach from tmux. &lt;br /&gt;
&lt;br /&gt;
Add IRC server if not already saved.&lt;br /&gt;
 /server add -auto -network Freenode irc.freenode.net 6667&lt;br /&gt;
Connect to server.&lt;br /&gt;
 /connect freenode&lt;br /&gt;
Can alternatively do &lt;br /&gt;
 /connect irc.freenode.net&lt;br /&gt;
Add your name to freenode, if not already saved (this is a benefit of saving the server)&lt;br /&gt;
 /network add -nick &amp;lt;your-nick&amp;gt; Freenode&lt;br /&gt;
When you login, you will want to register, if you haven't already. Then follow the server's&lt;br /&gt;
instructions for the password. The server's output often displays on a different window than your&lt;br /&gt;
default. So &lt;br /&gt;
 CTRL-N&lt;br /&gt;
to switch to the next IRSSI window.&lt;br /&gt;
&lt;br /&gt;
===Windows===&lt;br /&gt;
If you want a new window:&lt;br /&gt;
 /window new&lt;br /&gt;
If you want to get rid of the split window&lt;br /&gt;
 /window hide #&lt;br /&gt;
You might have to turn off the &amp;quot;sticky&amp;quot; window. It will prompt you if necessary, for example if you hit CTRL-N&lt;br /&gt;
&lt;br /&gt;
====Freenode Search====&lt;br /&gt;
Servers manage search differently. You can always /list, but that is too many to read. For freenode:&lt;br /&gt;
 /msg alis LIST * -topic electronics&lt;br /&gt;
There are more instructions here: https://freenode.net/kb/answer/findingchannels&lt;br /&gt;
But the help doc is outdated, and at least one of the examples doesn't work (2019/10). So just use above.&lt;br /&gt;
&lt;br /&gt;
After you search, scroll up pages in irssi default setup with:&lt;br /&gt;
 PageUp&lt;br /&gt;
Just the page up key. Much easier than screen which requires changing modes.&lt;br /&gt;
&lt;br /&gt;
====Logs====&lt;br /&gt;
 mkdir ~/irclogs&lt;br /&gt;
in irssi&lt;br /&gt;
 /SET autolog ON&lt;br /&gt;
login to server. quit irssi. verify that log was created.&lt;br /&gt;
ref: https://irssi.org/documentation/startup/#logging&lt;br /&gt;
&lt;br /&gt;
====Ignore parts, joins, quits====&lt;br /&gt;
&amp;lt;pre&amp;gt;/ignore * joins parts quits nicks&lt;br /&gt;
/save&amp;lt;/pre&amp;gt;&lt;br /&gt;
ref: https://www.rosipov.com/blog/irssi-ignore-all-from-everyone/&lt;br /&gt;
&lt;br /&gt;
===Other===&lt;br /&gt;
https://github.com/irssi/irssi/blob/master/docs/manual.txt&lt;br /&gt;
&lt;br /&gt;
From: &lt;br /&gt;
https://gist.github.com/tasdikrahman/ec4e46a42cbf38c73ef3af863680c786&lt;br /&gt;
&lt;br /&gt;
&amp;quot;The most important thing to know about navigating between windows is&lt;br /&gt;
that alt + a sends you to the window with the most recent, most&lt;br /&gt;
important activity. Pressing it consecutively will first lead you&lt;br /&gt;
through all windows that are pink in your activity bar, then all&lt;br /&gt;
windows that are white, and then the rest. This is not entirely&lt;br /&gt;
correct, but if you are able to correct me on this, you don’t need&lt;br /&gt;
this article in the first place :-)&lt;br /&gt;
&lt;br /&gt;
Then there are alt + 1, alt + 2 , and so on. These take you directly&lt;br /&gt;
to the window with that number. By default, the top 2 lines of your&lt;br /&gt;
(qwerty) keyboard are bound that way, all the way up to alt + o, which&lt;br /&gt;
takes you to window 19.&lt;br /&gt;
&lt;br /&gt;
Going to the next or previous window can be done by pressing ctrl + p&lt;br /&gt;
or ctrl + n, or via alt + arrow left or alt + arrow right.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==GNU Screen==&lt;br /&gt;
&lt;br /&gt;
scroll up&lt;br /&gt;
 ctrl-a ESC&lt;br /&gt;
 pgup / pgdn&lt;br /&gt;
output current screen buffer to file&lt;br /&gt;
 ctrl-a :&lt;br /&gt;
 hardcopy  output.file  (type this)&lt;br /&gt;
output whole screen buffer to file&lt;br /&gt;
 ctrl-a :&lt;br /&gt;
 hardcopy -h output.file&lt;br /&gt;
Note: if file seems blank at the top, scroll down.&lt;br /&gt;
connect w/serial&lt;br /&gt;
 # screen /dev/ttyS0 115200&lt;br /&gt;
&lt;br /&gt;
==Tmux==&lt;br /&gt;
&lt;br /&gt;
===Two ttys / logins with r/w to same terminal===&lt;br /&gt;
There is some misleading info about this online. If you search tmux multiple users, they will say not possible. Well maybe multiple users is wrong semantics. I want multiple logins to access the same terminal. They can be the same account. Therefore: &lt;br /&gt;
&lt;br /&gt;
in first terminal&lt;br /&gt;
&lt;br /&gt;
 tmux new-session -s shared&lt;br /&gt;
&lt;br /&gt;
Then in the second terminal attach to the shared session.&lt;br /&gt;
 tmux list-sessions&lt;br /&gt;
 tmux attach -t shared&lt;br /&gt;
key  here is -t must be used by the 2nd tmux.&lt;br /&gt;
ref: https://www.howtoforge.com/sharing-terminal-sessions-with-tmux-and-screen&lt;br /&gt;
and&lt;br /&gt;
ref: https://bbs.archlinux.org/viewtopic.php?id=213229&lt;br /&gt;
&lt;br /&gt;
'''why would you do this'''&lt;br /&gt;
&lt;br /&gt;
If you have a TFT on an RPI or [[Beaglebone]], you can edit the tft tty without logging in to it directly. Have the tft auto load a tmux session after a delay, and then connect into it from another acct.&lt;br /&gt;
&lt;br /&gt;
==Security on IRC==&lt;br /&gt;
Don't use your home internet connection, use a VPS. You can get VPS for extremely cheap ($10-15/yr) which are perfect for IRC.&lt;br /&gt;
&lt;br /&gt;
==IRC Gabbers (Politics)==&lt;br /&gt;
IRC support chats are not for socializing. No one has time to read your hugbox. Keep it simple, and to the point. Life is short.&lt;/div&gt;</summary>
		<author><name>Adminguy</name></author>
	</entry>
	<entry>
		<id>http://steakwiki.com/index.php?title=Irssi&amp;diff=984</id>
		<title>Irssi</title>
		<link rel="alternate" type="text/html" href="http://steakwiki.com/index.php?title=Irssi&amp;diff=984"/>
		<updated>2021-03-15T10:51:09Z</updated>

		<summary type="html">&lt;p&gt;Adminguy: /* Other */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Because discord and slack are proprietary.&lt;br /&gt;
&lt;br /&gt;
I've tried a few times to get into irssi, but realized the only way I'd be able to use it is with a long term running VPS, and documenting my steps here.&lt;br /&gt;
&lt;br /&gt;
==Usage==&lt;br /&gt;
Login to VPS. Start tmux with &lt;br /&gt;
 tmux new -s irssi irssi&lt;br /&gt;
If you later logout, you can re attach with:&lt;br /&gt;
 tmux attach -t irssi&lt;br /&gt;
or alternatively, if you only have one tmux window open:&lt;br /&gt;
 tmux attach&lt;br /&gt;
NOTE: You can close the window (I have a kill shortcut on F12) or ctrl-b d&lt;br /&gt;
to detach from tmux. &lt;br /&gt;
&lt;br /&gt;
Add IRC server if not already saved.&lt;br /&gt;
 /server add -auto -network Freenode irc.freenode.net 6667&lt;br /&gt;
Connect to server.&lt;br /&gt;
 /connect freenode&lt;br /&gt;
Can alternatively do &lt;br /&gt;
 /connect irc.freenode.net&lt;br /&gt;
Add your name to freenode, if not already saved (this is a benefit of saving the server)&lt;br /&gt;
 /network add -nick &amp;lt;your-nick&amp;gt; Freenode&lt;br /&gt;
When you login, you will want to register, if you haven't already. Then follow the server's&lt;br /&gt;
instructions for the password. The server's output often displays on a different window than your&lt;br /&gt;
default. So &lt;br /&gt;
 CTRL-N&lt;br /&gt;
to switch to the next IRSSI window.&lt;br /&gt;
&lt;br /&gt;
===Windows===&lt;br /&gt;
If you want a new window:&lt;br /&gt;
 /window new&lt;br /&gt;
If you want to get rid of the split window&lt;br /&gt;
 /window hide #&lt;br /&gt;
You might have to turn off the &amp;quot;sticky&amp;quot; window. It will prompt you if necessary, for example if you hit CTRL-N&lt;br /&gt;
&lt;br /&gt;
====Freenode Search====&lt;br /&gt;
Servers manage search differently. You can always /list, but that is too many to read. For freenode:&lt;br /&gt;
 /msg alis LIST * -topic electronics&lt;br /&gt;
There are more instructions here: https://freenode.net/kb/answer/findingchannels&lt;br /&gt;
But the help doc is outdated, and at least one of the examples doesn't work (2019/10). So just use above.&lt;br /&gt;
&lt;br /&gt;
After you search, scroll up pages in irssi default setup with:&lt;br /&gt;
 PageUp&lt;br /&gt;
Just the page up key. Much easier than screen which requires changing modes.&lt;br /&gt;
&lt;br /&gt;
====Logs====&lt;br /&gt;
 mkdir ~/irclogs&lt;br /&gt;
in irssi&lt;br /&gt;
 /SET autolog ON&lt;br /&gt;
login to server. quit irssi. verify that log was created.&lt;br /&gt;
ref: https://irssi.org/documentation/startup/#logging&lt;br /&gt;
&lt;br /&gt;
====Ignore parts, joins, quits====&lt;br /&gt;
&amp;lt;pre&amp;gt;/ignore * joins parts quits nicks&lt;br /&gt;
/save&amp;lt;/pre&amp;gt;&lt;br /&gt;
ref: https://www.rosipov.com/blog/irssi-ignore-all-from-everyone/&lt;br /&gt;
&lt;br /&gt;
===Other===&lt;br /&gt;
https://github.com/irssi/irssi/blob/master/docs/manual.txt&lt;br /&gt;
&lt;br /&gt;
The below is from: &lt;br /&gt;
https://gist.github.com/tasdikrahman/ec4e46a42cbf38c73ef3af863680c786&lt;br /&gt;
&lt;br /&gt;
&amp;quot;The most important thing to know about navigating between windows is&lt;br /&gt;
that alt + a sends you to the window with the most recent, most&lt;br /&gt;
important activity. Pressing it consecutively will first lead you&lt;br /&gt;
through all windows that are pink in your activity bar, then all&lt;br /&gt;
windows that are white, and then the rest. This is not entirely&lt;br /&gt;
correct, but if you are able to correct me on this, you don’t need&lt;br /&gt;
this article in the first place :-)&lt;br /&gt;
&lt;br /&gt;
Then there are alt + 1, alt + 2 , and so on. These take you directly&lt;br /&gt;
to the window with that number. By default, the top 2 lines of your&lt;br /&gt;
(qwerty) keyboard are bound that way, all the way up to alt + o, which&lt;br /&gt;
takes you to window 19.&lt;br /&gt;
&lt;br /&gt;
Going to the next or previous window can be done by pressing ctrl + p&lt;br /&gt;
or ctrl + n, or via alt + arrow left or alt + arrow right.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==GNU Screen==&lt;br /&gt;
&lt;br /&gt;
scroll up&lt;br /&gt;
 ctrl-a ESC&lt;br /&gt;
 pgup / pgdn&lt;br /&gt;
output current screen buffer to file&lt;br /&gt;
 ctrl-a :&lt;br /&gt;
 hardcopy  output.file  (type this)&lt;br /&gt;
output whole screen buffer to file&lt;br /&gt;
 ctrl-a :&lt;br /&gt;
 hardcopy -h output.file&lt;br /&gt;
Note: if file seems blank at the top, scroll down.&lt;br /&gt;
connect w/serial&lt;br /&gt;
 # screen /dev/ttyS0 115200&lt;br /&gt;
&lt;br /&gt;
==Tmux==&lt;br /&gt;
&lt;br /&gt;
===Two ttys / logins with r/w to same terminal===&lt;br /&gt;
There is some misleading info about this online. If you search tmux multiple users, they will say not possible. Well maybe multiple users is wrong semantics. I want multiple logins to access the same terminal. They can be the same account. Therefore: &lt;br /&gt;
&lt;br /&gt;
in first terminal&lt;br /&gt;
&lt;br /&gt;
 tmux new-session -s shared&lt;br /&gt;
&lt;br /&gt;
Then in the second terminal attach to the shared session.&lt;br /&gt;
 tmux list-sessions&lt;br /&gt;
 tmux attach -t shared&lt;br /&gt;
key  here is -t must be used by the 2nd tmux.&lt;br /&gt;
ref: https://www.howtoforge.com/sharing-terminal-sessions-with-tmux-and-screen&lt;br /&gt;
and&lt;br /&gt;
ref: https://bbs.archlinux.org/viewtopic.php?id=213229&lt;br /&gt;
&lt;br /&gt;
'''why would you do this'''&lt;br /&gt;
&lt;br /&gt;
If you have a TFT on an RPI or [[Beaglebone]], you can edit the tft tty without logging in to it directly. Have the tft auto load a tmux session after a delay, and then connect into it from another acct.&lt;br /&gt;
&lt;br /&gt;
==Security on IRC==&lt;br /&gt;
Don't use your home internet connection, use a VPS. You can get VPS for extremely cheap ($10-15/yr) which are perfect for IRC.&lt;br /&gt;
&lt;br /&gt;
==IRC Gabbers (Politics)==&lt;br /&gt;
IRC support chats are not for socializing. No one has time to read your hugbox. Keep it simple, and to the point. Life is short.&lt;/div&gt;</summary>
		<author><name>Adminguy</name></author>
	</entry>
	<entry>
		<id>http://steakwiki.com/index.php?title=Irssi&amp;diff=983</id>
		<title>Irssi</title>
		<link rel="alternate" type="text/html" href="http://steakwiki.com/index.php?title=Irssi&amp;diff=983"/>
		<updated>2021-03-15T10:50:04Z</updated>

		<summary type="html">&lt;p&gt;Adminguy: /* Windows */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Because discord and slack are proprietary.&lt;br /&gt;
&lt;br /&gt;
I've tried a few times to get into irssi, but realized the only way I'd be able to use it is with a long term running VPS, and documenting my steps here.&lt;br /&gt;
&lt;br /&gt;
==Usage==&lt;br /&gt;
Login to VPS. Start tmux with &lt;br /&gt;
 tmux new -s irssi irssi&lt;br /&gt;
If you later logout, you can re attach with:&lt;br /&gt;
 tmux attach -t irssi&lt;br /&gt;
or alternatively, if you only have one tmux window open:&lt;br /&gt;
 tmux attach&lt;br /&gt;
NOTE: You can close the window (I have a kill shortcut on F12) or ctrl-b d&lt;br /&gt;
to detach from tmux. &lt;br /&gt;
&lt;br /&gt;
Add IRC server if not already saved.&lt;br /&gt;
 /server add -auto -network Freenode irc.freenode.net 6667&lt;br /&gt;
Connect to server.&lt;br /&gt;
 /connect freenode&lt;br /&gt;
Can alternatively do &lt;br /&gt;
 /connect irc.freenode.net&lt;br /&gt;
Add your name to freenode, if not already saved (this is a benefit of saving the server)&lt;br /&gt;
 /network add -nick &amp;lt;your-nick&amp;gt; Freenode&lt;br /&gt;
When you login, you will want to register, if you haven't already. Then follow the server's&lt;br /&gt;
instructions for the password. The server's output often displays on a different window than your&lt;br /&gt;
default. So &lt;br /&gt;
 CTRL-N&lt;br /&gt;
to switch to the next IRSSI window.&lt;br /&gt;
&lt;br /&gt;
===Windows===&lt;br /&gt;
If you want a new window:&lt;br /&gt;
 /window new&lt;br /&gt;
If you want to get rid of the split window&lt;br /&gt;
 /window hide #&lt;br /&gt;
You might have to turn off the &amp;quot;sticky&amp;quot; window. It will prompt you if necessary, for example if you hit CTRL-N&lt;br /&gt;
&lt;br /&gt;
====Freenode Search====&lt;br /&gt;
Servers manage search differently. You can always /list, but that is too many to read. For freenode:&lt;br /&gt;
 /msg alis LIST * -topic electronics&lt;br /&gt;
There are more instructions here: https://freenode.net/kb/answer/findingchannels&lt;br /&gt;
But the help doc is outdated, and at least one of the examples doesn't work (2019/10). So just use above.&lt;br /&gt;
&lt;br /&gt;
After you search, scroll up pages in irssi default setup with:&lt;br /&gt;
 PageUp&lt;br /&gt;
Just the page up key. Much easier than screen which requires changing modes.&lt;br /&gt;
&lt;br /&gt;
====Logs====&lt;br /&gt;
 mkdir ~/irclogs&lt;br /&gt;
in irssi&lt;br /&gt;
 /SET autolog ON&lt;br /&gt;
login to server. quit irssi. verify that log was created.&lt;br /&gt;
ref: https://irssi.org/documentation/startup/#logging&lt;br /&gt;
&lt;br /&gt;
====Ignore parts, joins, quits====&lt;br /&gt;
&amp;lt;pre&amp;gt;/ignore * joins parts quits nicks&lt;br /&gt;
/save&amp;lt;/pre&amp;gt;&lt;br /&gt;
ref: https://www.rosipov.com/blog/irssi-ignore-all-from-everyone/&lt;br /&gt;
&lt;br /&gt;
===Other===&lt;br /&gt;
https://github.com/irssi/irssi/blob/master/docs/manual.txt&lt;br /&gt;
&lt;br /&gt;
ref: &lt;br /&gt;
https://gist.github.com/tasdikrahman/ec4e46a42cbf38c73ef3af863680c786&lt;br /&gt;
&lt;br /&gt;
The most important thing to know about navigating between windows is&lt;br /&gt;
that alt + a sends you to the window with the most recent, most&lt;br /&gt;
important activity. Pressing it consecutively will first lead you&lt;br /&gt;
through all windows that are pink in your activity bar, then all&lt;br /&gt;
windows that are white, and then the rest. This is not entirely&lt;br /&gt;
correct, but if you are able to correct me on this, you don’t need&lt;br /&gt;
this article in the first place :-)&lt;br /&gt;
&lt;br /&gt;
Then there are alt + 1, alt + 2 , and so on. These take you directly&lt;br /&gt;
to the window with that number. By default, the top 2 lines of your&lt;br /&gt;
(qwerty) keyboard are bound that way, all the way up to alt + o, which&lt;br /&gt;
takes you to window 19.&lt;br /&gt;
&lt;br /&gt;
Going to the next or previous window can be done by pressing ctrl + p&lt;br /&gt;
or ctrl + n, or via alt + arrow left or alt + arrow right.&lt;br /&gt;
&lt;br /&gt;
==GNU Screen==&lt;br /&gt;
&lt;br /&gt;
scroll up&lt;br /&gt;
 ctrl-a ESC&lt;br /&gt;
 pgup / pgdn&lt;br /&gt;
output current screen buffer to file&lt;br /&gt;
 ctrl-a :&lt;br /&gt;
 hardcopy  output.file  (type this)&lt;br /&gt;
output whole screen buffer to file&lt;br /&gt;
 ctrl-a :&lt;br /&gt;
 hardcopy -h output.file&lt;br /&gt;
Note: if file seems blank at the top, scroll down.&lt;br /&gt;
connect w/serial&lt;br /&gt;
 # screen /dev/ttyS0 115200&lt;br /&gt;
&lt;br /&gt;
==Tmux==&lt;br /&gt;
&lt;br /&gt;
===Two ttys / logins with r/w to same terminal===&lt;br /&gt;
There is some misleading info about this online. If you search tmux multiple users, they will say not possible. Well maybe multiple users is wrong semantics. I want multiple logins to access the same terminal. They can be the same account. Therefore: &lt;br /&gt;
&lt;br /&gt;
in first terminal&lt;br /&gt;
&lt;br /&gt;
 tmux new-session -s shared&lt;br /&gt;
&lt;br /&gt;
Then in the second terminal attach to the shared session.&lt;br /&gt;
 tmux list-sessions&lt;br /&gt;
 tmux attach -t shared&lt;br /&gt;
key  here is -t must be used by the 2nd tmux.&lt;br /&gt;
ref: https://www.howtoforge.com/sharing-terminal-sessions-with-tmux-and-screen&lt;br /&gt;
and&lt;br /&gt;
ref: https://bbs.archlinux.org/viewtopic.php?id=213229&lt;br /&gt;
&lt;br /&gt;
'''why would you do this'''&lt;br /&gt;
&lt;br /&gt;
If you have a TFT on an RPI or [[Beaglebone]], you can edit the tft tty without logging in to it directly. Have the tft auto load a tmux session after a delay, and then connect into it from another acct.&lt;br /&gt;
&lt;br /&gt;
==Security on IRC==&lt;br /&gt;
Don't use your home internet connection, use a VPS. You can get VPS for extremely cheap ($10-15/yr) which are perfect for IRC.&lt;br /&gt;
&lt;br /&gt;
==IRC Gabbers (Politics)==&lt;br /&gt;
IRC support chats are not for socializing. No one has time to read your hugbox. Keep it simple, and to the point. Life is short.&lt;/div&gt;</summary>
		<author><name>Adminguy</name></author>
	</entry>
	<entry>
		<id>http://steakwiki.com/index.php?title=Alpine&amp;diff=982</id>
		<title>Alpine</title>
		<link rel="alternate" type="text/html" href="http://steakwiki.com/index.php?title=Alpine&amp;diff=982"/>
		<updated>2021-03-03T10:22:30Z</updated>

		<summary type="html">&lt;p&gt;Adminguy: /* Search for library */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;small&amp;gt;&lt;br /&gt;
==General Tips==&lt;br /&gt;
===Building a package in Alpine===&lt;br /&gt;
&lt;br /&gt;
https://wiki.alpinelinux.org/wiki/Category_talk:Developer_Documentation#Building_from_source_and_creating_packages&lt;br /&gt;
&lt;br /&gt;
https://wiki.alpinelinux.org/wiki/Custom_Kernel&lt;br /&gt;
&lt;br /&gt;
===Xorg video playback stutters upon suspend / resume===&lt;br /&gt;
&lt;br /&gt;
I added the following configuration to xorg.conf&lt;br /&gt;
 Section &amp;quot;Device&amp;quot;&lt;br /&gt;
   Identifier &amp;quot;Intel Graphics&amp;quot;&lt;br /&gt;
   Driver &amp;quot;intel&amp;quot;&lt;br /&gt;
   Option &amp;quot;AccelMethod&amp;quot; &amp;quot;uxa&amp;quot;&lt;br /&gt;
 EndSection&lt;br /&gt;
&lt;br /&gt;
This seems to resolve video playback issues. What happens is that the video will not play, though audio will. Only the first frame or so is visible. Video seems to be unable to display. This is a documented fix. The important part is AccelMethod.&lt;br /&gt;
https://wiki.archlinux.org/index.php/Intel_Graphics&lt;br /&gt;
Also documented in forums that I can't seem to find at the moment.&lt;br /&gt;
&lt;br /&gt;
===Python3 Script Won't Run===&lt;br /&gt;
 $ ztdl&lt;br /&gt;
 env: can't execute python&lt;br /&gt;
solution:&lt;br /&gt;
 python3 /usr/local/bin/ztdl&lt;br /&gt;
&lt;br /&gt;
===Cloning HDD===&lt;br /&gt;
&lt;br /&gt;
When cloning a hdd, do the&lt;br /&gt;
following:&lt;br /&gt;
*clonezilla or otherwise rsync partitions and recreate partitions to similar boundaries&lt;br /&gt;
by default clonezilla might fail, due to -C not being set. There is an icds option for restore, but it can either be edited into /usr/sbin/ocs-onthefly  for partclone or just rsync then:&lt;br /&gt;
*edit etc fstab  uuids&lt;br /&gt;
*edit (boot partition) grub/grub.cfg root=uuid=whatever to root=/dev/sda3&lt;br /&gt;
*can also be in /dev/sda1 - extlinux.conf&lt;br /&gt;
NOTE: normal editing of extlinux.conf can also be done with the extlinux in /etc/&lt;br /&gt;
&lt;br /&gt;
===Kernel, Initramfs recovery===&lt;br /&gt;
If upgrade fails halfway through for any reason (hdd failing, system in a broken state), you may be left with a unbootable machine. Keep an extra /boot/vmlinuz-lts and /boot/initramfs-lts and also a copy of that kernels /lib/modules/&amp;lt;kernelvers&amp;gt; around in case. I keep mine in a folder named /boot/recovery. Backup hdds help here. If you have a corrupt initramfs, or kernel, move the old files back over to /boot from another machine. Now, from the alpine machine (not from a different dist chroot, which didn't work for me btw), boot up, and run mkinitfs again. The command is easy to mess up, so here's the correct one (as of 3.12)&lt;br /&gt;
 mkinitfs -c /etc/mkinitfs/mkinitfs.conf -b / &amp;lt;kernelvers&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The kernel vers for the new kernel can be found from /lib/modules. It should also have a folder, as the script will load modules into the initramfs&lt;br /&gt;
ref:&lt;br /&gt;
https://wiki.alpinelinux.org/wiki/Running_Alpine_in_a_Docker_Container&lt;br /&gt;
&lt;br /&gt;
https://wiki.alpinelinux.org/wiki/NVME&lt;br /&gt;
&lt;br /&gt;
https://wiki.alpinelinux.org/wiki/Bootloaders&lt;br /&gt;
&lt;br /&gt;
https://wiki.alpinelinux.org/wiki/Setting_up_a_software_RAID_array&lt;br /&gt;
&lt;br /&gt;
===UTF-8 Characters===&lt;br /&gt;
If you see certain foreign language characters not showing up correctly, you can try installing different fonts.&lt;br /&gt;
 apk search ttf&lt;br /&gt;
But I found that changing in FF opensans to sans-serif fixed some of them for me. opensans had partial support for international characters.&lt;br /&gt;
&lt;br /&gt;
===History File Size===&lt;br /&gt;
Alpine uses ash, not bash. &lt;br /&gt;
 printenv&lt;br /&gt;
Histfilesize / histsize should be set correctly.&lt;br /&gt;
&lt;br /&gt;
===Search for package===&lt;br /&gt;
There's obv &lt;br /&gt;
 apk search &amp;lt;packagename&amp;gt; &lt;br /&gt;
but, there is also&lt;br /&gt;
 apk search -v --description 'something descriptive'&lt;br /&gt;
e.g.&lt;br /&gt;
 apk search -v --description 'browser'&lt;br /&gt;
&lt;br /&gt;
===Search for who owns a certain file===&lt;br /&gt;
 apk info -W ./somefile.so&lt;br /&gt;
Some info options (omitted a few):&amp;lt;pre&amp;gt;&lt;br /&gt;
Info options:&lt;br /&gt;
  -L, --contents          List contents of the PACKAGE&lt;br /&gt;
  -e, --installed         Check if PACKAGE is installed&lt;br /&gt;
  -W, --who-owns          Print the package owning the specified file&lt;br /&gt;
  -R, --depends           List packages that the PACKAGE depends on&lt;br /&gt;
  -r, --rdepends          List all packages depending on PACKAGE&lt;br /&gt;
  --replaces              List packages whom files PACKAGE might replace&lt;br /&gt;
  -w, --webpage           Show URL for more information about PACKAGE&lt;br /&gt;
  -s, --size              Show installed size of PACKAGE&lt;br /&gt;
  -d, --description       Print description for PACKAGE&lt;br /&gt;
  -a, --all               Print all information about PACKAGE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Links==&lt;br /&gt;
https://wiki.alpinelinux.org/wiki/Configure_Wake-on-LAN Configure_Wake-on-LAN&lt;br /&gt;
&lt;br /&gt;
gcompat - way to run glibc programs&lt;br /&gt;
&lt;br /&gt;
https://wiki.alpinelinux.org/wiki/Running_glibc_programs&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{GNU\Linux}}&lt;/div&gt;</summary>
		<author><name>Adminguy</name></author>
	</entry>
	<entry>
		<id>http://steakwiki.com/index.php?title=Alpine&amp;diff=981</id>
		<title>Alpine</title>
		<link rel="alternate" type="text/html" href="http://steakwiki.com/index.php?title=Alpine&amp;diff=981"/>
		<updated>2021-03-03T10:15:26Z</updated>

		<summary type="html">&lt;p&gt;Adminguy: /* Search for library */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;small&amp;gt;&lt;br /&gt;
==General Tips==&lt;br /&gt;
===Building a package in Alpine===&lt;br /&gt;
&lt;br /&gt;
https://wiki.alpinelinux.org/wiki/Category_talk:Developer_Documentation#Building_from_source_and_creating_packages&lt;br /&gt;
&lt;br /&gt;
https://wiki.alpinelinux.org/wiki/Custom_Kernel&lt;br /&gt;
&lt;br /&gt;
===Xorg video playback stutters upon suspend / resume===&lt;br /&gt;
&lt;br /&gt;
I added the following configuration to xorg.conf&lt;br /&gt;
 Section &amp;quot;Device&amp;quot;&lt;br /&gt;
   Identifier &amp;quot;Intel Graphics&amp;quot;&lt;br /&gt;
   Driver &amp;quot;intel&amp;quot;&lt;br /&gt;
   Option &amp;quot;AccelMethod&amp;quot; &amp;quot;uxa&amp;quot;&lt;br /&gt;
 EndSection&lt;br /&gt;
&lt;br /&gt;
This seems to resolve video playback issues. What happens is that the video will not play, though audio will. Only the first frame or so is visible. Video seems to be unable to display. This is a documented fix. The important part is AccelMethod.&lt;br /&gt;
https://wiki.archlinux.org/index.php/Intel_Graphics&lt;br /&gt;
Also documented in forums that I can't seem to find at the moment.&lt;br /&gt;
&lt;br /&gt;
===Python3 Script Won't Run===&lt;br /&gt;
 $ ztdl&lt;br /&gt;
 env: can't execute python&lt;br /&gt;
solution:&lt;br /&gt;
 python3 /usr/local/bin/ztdl&lt;br /&gt;
&lt;br /&gt;
===Cloning HDD===&lt;br /&gt;
&lt;br /&gt;
When cloning a hdd, do the&lt;br /&gt;
following:&lt;br /&gt;
*clonezilla or otherwise rsync partitions and recreate partitions to similar boundaries&lt;br /&gt;
by default clonezilla might fail, due to -C not being set. There is an icds option for restore, but it can either be edited into /usr/sbin/ocs-onthefly  for partclone or just rsync then:&lt;br /&gt;
*edit etc fstab  uuids&lt;br /&gt;
*edit (boot partition) grub/grub.cfg root=uuid=whatever to root=/dev/sda3&lt;br /&gt;
*can also be in /dev/sda1 - extlinux.conf&lt;br /&gt;
NOTE: normal editing of extlinux.conf can also be done with the extlinux in /etc/&lt;br /&gt;
&lt;br /&gt;
===Kernel, Initramfs recovery===&lt;br /&gt;
If upgrade fails halfway through for any reason (hdd failing, system in a broken state), you may be left with a unbootable machine. Keep an extra /boot/vmlinuz-lts and /boot/initramfs-lts and also a copy of that kernels /lib/modules/&amp;lt;kernelvers&amp;gt; around in case. I keep mine in a folder named /boot/recovery. Backup hdds help here. If you have a corrupt initramfs, or kernel, move the old files back over to /boot from another machine. Now, from the alpine machine (not from a different dist chroot, which didn't work for me btw), boot up, and run mkinitfs again. The command is easy to mess up, so here's the correct one (as of 3.12)&lt;br /&gt;
 mkinitfs -c /etc/mkinitfs/mkinitfs.conf -b / &amp;lt;kernelvers&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The kernel vers for the new kernel can be found from /lib/modules. It should also have a folder, as the script will load modules into the initramfs&lt;br /&gt;
ref:&lt;br /&gt;
https://wiki.alpinelinux.org/wiki/Running_Alpine_in_a_Docker_Container&lt;br /&gt;
&lt;br /&gt;
https://wiki.alpinelinux.org/wiki/NVME&lt;br /&gt;
&lt;br /&gt;
https://wiki.alpinelinux.org/wiki/Bootloaders&lt;br /&gt;
&lt;br /&gt;
https://wiki.alpinelinux.org/wiki/Setting_up_a_software_RAID_array&lt;br /&gt;
&lt;br /&gt;
===UTF-8 Characters===&lt;br /&gt;
If you see certain foreign language characters not showing up correctly, you can try installing different fonts.&lt;br /&gt;
 apk search ttf&lt;br /&gt;
But I found that changing in FF opensans to sans-serif fixed some of them for me. opensans had partial support for international characters.&lt;br /&gt;
&lt;br /&gt;
===History File Size===&lt;br /&gt;
Alpine uses ash, not bash. &lt;br /&gt;
 printenv&lt;br /&gt;
Histfilesize / histsize should be set correctly.&lt;br /&gt;
&lt;br /&gt;
===Search for package===&lt;br /&gt;
There's obv &lt;br /&gt;
 apk search &amp;lt;packagename&amp;gt; &lt;br /&gt;
but, there is also&lt;br /&gt;
 apk search -v --description 'something descriptive'&lt;br /&gt;
e.g.&lt;br /&gt;
 apk search -v --description 'browser'&lt;br /&gt;
&lt;br /&gt;
===Search for library===&lt;br /&gt;
 apk info -W /usr/includes/somelib.h&lt;br /&gt;
&lt;br /&gt;
==Links==&lt;br /&gt;
https://wiki.alpinelinux.org/wiki/Configure_Wake-on-LAN Configure_Wake-on-LAN&lt;br /&gt;
&lt;br /&gt;
gcompat - way to run glibc programs&lt;br /&gt;
&lt;br /&gt;
https://wiki.alpinelinux.org/wiki/Running_glibc_programs&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{GNU\Linux}}&lt;/div&gt;</summary>
		<author><name>Adminguy</name></author>
	</entry>
	<entry>
		<id>http://steakwiki.com/index.php?title=Alpine&amp;diff=980</id>
		<title>Alpine</title>
		<link rel="alternate" type="text/html" href="http://steakwiki.com/index.php?title=Alpine&amp;diff=980"/>
		<updated>2021-03-03T10:14:51Z</updated>

		<summary type="html">&lt;p&gt;Adminguy: /* Search for package */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;small&amp;gt;&lt;br /&gt;
==General Tips==&lt;br /&gt;
===Building a package in Alpine===&lt;br /&gt;
&lt;br /&gt;
https://wiki.alpinelinux.org/wiki/Category_talk:Developer_Documentation#Building_from_source_and_creating_packages&lt;br /&gt;
&lt;br /&gt;
https://wiki.alpinelinux.org/wiki/Custom_Kernel&lt;br /&gt;
&lt;br /&gt;
===Xorg video playback stutters upon suspend / resume===&lt;br /&gt;
&lt;br /&gt;
I added the following configuration to xorg.conf&lt;br /&gt;
 Section &amp;quot;Device&amp;quot;&lt;br /&gt;
   Identifier &amp;quot;Intel Graphics&amp;quot;&lt;br /&gt;
   Driver &amp;quot;intel&amp;quot;&lt;br /&gt;
   Option &amp;quot;AccelMethod&amp;quot; &amp;quot;uxa&amp;quot;&lt;br /&gt;
 EndSection&lt;br /&gt;
&lt;br /&gt;
This seems to resolve video playback issues. What happens is that the video will not play, though audio will. Only the first frame or so is visible. Video seems to be unable to display. This is a documented fix. The important part is AccelMethod.&lt;br /&gt;
https://wiki.archlinux.org/index.php/Intel_Graphics&lt;br /&gt;
Also documented in forums that I can't seem to find at the moment.&lt;br /&gt;
&lt;br /&gt;
===Python3 Script Won't Run===&lt;br /&gt;
 $ ztdl&lt;br /&gt;
 env: can't execute python&lt;br /&gt;
solution:&lt;br /&gt;
 python3 /usr/local/bin/ztdl&lt;br /&gt;
&lt;br /&gt;
===Cloning HDD===&lt;br /&gt;
&lt;br /&gt;
When cloning a hdd, do the&lt;br /&gt;
following:&lt;br /&gt;
*clonezilla or otherwise rsync partitions and recreate partitions to similar boundaries&lt;br /&gt;
by default clonezilla might fail, due to -C not being set. There is an icds option for restore, but it can either be edited into /usr/sbin/ocs-onthefly  for partclone or just rsync then:&lt;br /&gt;
*edit etc fstab  uuids&lt;br /&gt;
*edit (boot partition) grub/grub.cfg root=uuid=whatever to root=/dev/sda3&lt;br /&gt;
*can also be in /dev/sda1 - extlinux.conf&lt;br /&gt;
NOTE: normal editing of extlinux.conf can also be done with the extlinux in /etc/&lt;br /&gt;
&lt;br /&gt;
===Kernel, Initramfs recovery===&lt;br /&gt;
If upgrade fails halfway through for any reason (hdd failing, system in a broken state), you may be left with a unbootable machine. Keep an extra /boot/vmlinuz-lts and /boot/initramfs-lts and also a copy of that kernels /lib/modules/&amp;lt;kernelvers&amp;gt; around in case. I keep mine in a folder named /boot/recovery. Backup hdds help here. If you have a corrupt initramfs, or kernel, move the old files back over to /boot from another machine. Now, from the alpine machine (not from a different dist chroot, which didn't work for me btw), boot up, and run mkinitfs again. The command is easy to mess up, so here's the correct one (as of 3.12)&lt;br /&gt;
 mkinitfs -c /etc/mkinitfs/mkinitfs.conf -b / &amp;lt;kernelvers&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The kernel vers for the new kernel can be found from /lib/modules. It should also have a folder, as the script will load modules into the initramfs&lt;br /&gt;
ref:&lt;br /&gt;
https://wiki.alpinelinux.org/wiki/Running_Alpine_in_a_Docker_Container&lt;br /&gt;
&lt;br /&gt;
https://wiki.alpinelinux.org/wiki/NVME&lt;br /&gt;
&lt;br /&gt;
https://wiki.alpinelinux.org/wiki/Bootloaders&lt;br /&gt;
&lt;br /&gt;
https://wiki.alpinelinux.org/wiki/Setting_up_a_software_RAID_array&lt;br /&gt;
&lt;br /&gt;
===UTF-8 Characters===&lt;br /&gt;
If you see certain foreign language characters not showing up correctly, you can try installing different fonts.&lt;br /&gt;
 apk search ttf&lt;br /&gt;
But I found that changing in FF opensans to sans-serif fixed some of them for me. opensans had partial support for international characters.&lt;br /&gt;
&lt;br /&gt;
===History File Size===&lt;br /&gt;
Alpine uses ash, not bash. &lt;br /&gt;
 printenv&lt;br /&gt;
Histfilesize / histsize should be set correctly.&lt;br /&gt;
&lt;br /&gt;
===Search for package===&lt;br /&gt;
There's obv &lt;br /&gt;
 apk search &amp;lt;packagename&amp;gt; &lt;br /&gt;
but, there is also&lt;br /&gt;
 apk search -v --description 'something descriptive'&lt;br /&gt;
e.g.&lt;br /&gt;
 apk search -v --description 'browser'&lt;br /&gt;
&lt;br /&gt;
===Search for library===&lt;br /&gt;
apk info -W /usr/includes/somelib.h&lt;br /&gt;
&lt;br /&gt;
==Links==&lt;br /&gt;
https://wiki.alpinelinux.org/wiki/Configure_Wake-on-LAN Configure_Wake-on-LAN&lt;br /&gt;
&lt;br /&gt;
gcompat - way to run glibc programs&lt;br /&gt;
&lt;br /&gt;
https://wiki.alpinelinux.org/wiki/Running_glibc_programs&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{GNU\Linux}}&lt;/div&gt;</summary>
		<author><name>Adminguy</name></author>
	</entry>
	<entry>
		<id>http://steakwiki.com/index.php?title=Unix_Commands&amp;diff=979</id>
		<title>Unix Commands</title>
		<link rel="alternate" type="text/html" href="http://steakwiki.com/index.php?title=Unix_Commands&amp;diff=979"/>
		<updated>2021-02-25T22:27:49Z</updated>

		<summary type="html">&lt;p&gt;Adminguy: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;some years of gnulinux, commands i have found easy to understand, yet still useful&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 find . -print | grep &amp;lt;somefile&amp;gt;&lt;br /&gt;
 find . -printf '$TY-%Tm-%Td %p\n' | grep 2020-12-29&lt;br /&gt;
 stat /files/* | grep -A5 &amp;lt;somenameoffile&amp;gt;  | awk 'xor(/File/,/Modify/)' &amp;gt; /tmp/dates&lt;br /&gt;
 sed -e 's/original/new/g' -i editfileinplace.txt&lt;br /&gt;
 grep 'one|two|three'  -search multiple items (may want to add -i to ignore case)&lt;br /&gt;
&lt;br /&gt;
edit .bashrc&lt;br /&gt;
 alias hs=&amp;quot;history&amp;quot;&lt;br /&gt;
&lt;br /&gt;
===Useful but less intuitive commands===&lt;br /&gt;
To get file counts for all directories (say you want to know how bloated / lean a software project is)&lt;br /&gt;
 du -a | cut -d/ -f2 | sort | uniq -c | sort -nr&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Resources: Unix Power Tools 1993&lt;/div&gt;</summary>
		<author><name>Adminguy</name></author>
	</entry>
	<entry>
		<id>http://steakwiki.com/index.php?title=Docker&amp;diff=978</id>
		<title>Docker</title>
		<link rel="alternate" type="text/html" href="http://steakwiki.com/index.php?title=Docker&amp;diff=978"/>
		<updated>2021-02-25T22:13:35Z</updated>

		<summary type="html">&lt;p&gt;Adminguy: /* Creating a docker-compose with a stable or latest tag */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;small&amp;gt;Docker is a type of virtualization for Gnu\Linux that allows programs to run and share similar resources, without having a full OS for each image, but while still isolating each 'vm'.&lt;br /&gt;
&lt;br /&gt;
==General Tips==&lt;br /&gt;
It helps to read a book, and then keep it as a Reference. Here Using Docker By Adrian Mouat is a decent book. In fact, you should be reading books on any subject that interests you. Physical paper books, too.&lt;br /&gt;
&lt;br /&gt;
Docker is x86_64. ARM has a separate build. There is no i386.&lt;br /&gt;
&lt;br /&gt;
You will want 'some' RAM. I had 1GB on a P4 machine, and that was not enough. 4GB was enough. &lt;br /&gt;
&lt;br /&gt;
You should always use docker compose. Docker is possible to run on the command line, but with a compose file, you can write everything down in a much simpler fashion. Use compose. It's a separate install, currently. Install it. ''Seriously, just ignore the docker command lines. I consider them useless. More of a red herring for rookies.''&lt;br /&gt;
&lt;br /&gt;
===ARM is SOL===&lt;br /&gt;
I tried to use Docker on ARM, and while you might be able to install docker, you will find that images for your applications may not be there. e.g. you will find Nginx, but you won't find Gitlab. This means that docker is pretty much x86-64 only.&lt;br /&gt;
&lt;br /&gt;
==Docker Commands==&lt;br /&gt;
Here are commands you need to know. Just the necessary ones.&lt;br /&gt;
{{cmd| docker-compose up -d}} &lt;br /&gt;
 &lt;br /&gt;
Starts the containers in the docker compose file, if they aren't already started. the -d detaches from the stdout logging. You don't need to use stdout logging, you can use docker logs, but its there if you want it.&lt;br /&gt;
 {{cmd| docker ps }}&lt;br /&gt;
Lists containers running. If one fails to start, you'll see it missing from here&lt;br /&gt;
 {{cmd|docker logs &amp;lt;containername&amp;gt; }}&lt;br /&gt;
Gives you some logging output from the container. Often enough to troubleshoot. (also see tips below).&lt;br /&gt;
 {{cmd|docker exec -it &amp;lt;containername&amp;gt; /bin/bash}}&lt;br /&gt;
This will get you in a shell in the docker container. From here you can do what you need to. Most are debian, and need apt-get install less nano or whatever program you are missing. Ping is missing from possibly all containers, so if you want to test via ping, you'll have to apt-get it.&lt;br /&gt;
 {{cmd|docker-compose restart }}&lt;br /&gt;
This will restart all containers. However, I don't recommend it. Initting containers can get corrupted this way, and also its much easier to restart a single faulty container via...&lt;br /&gt;
 {{cmd|docker restart &amp;lt;containername&amp;gt; }}&lt;br /&gt;
This will restart one single container.&lt;br /&gt;
 {{cmd|docker cp &amp;lt;containername&amp;gt;:/dir/to/file dest }}&lt;br /&gt;
You can copy files from local machine to docker, or vice versa with this. Extremely useful.&lt;br /&gt;
&lt;br /&gt;
===Deleting Containers===&lt;br /&gt;
Less often, you might want to know &lt;br /&gt;
{{cmd|&lt;br /&gt;
 #!/bin/bash&lt;br /&gt;
 docker rm $(docker ps -a -q)&lt;br /&gt;
 docker rmi $(docker images -q) --force}}&lt;br /&gt;
&lt;br /&gt;
This starts over from scratch. This is how easy it is to reboot a docker from square one.  note: below command (rmi), only needed if you want to remove base images. Needed when updating a stable. Not needed when changing other parameters not related to base image. Also, this deletes all containers, which maybe you don't want to do, if you either A) only want to delete certain images you are testing B) have some containers with custom changes saved, and not backed up elsewhere.&lt;br /&gt;
&lt;br /&gt;
===Updating===&lt;br /&gt;
 docker images&lt;br /&gt;
 (shows out of date image)&lt;br /&gt;
 docker pull mysql&lt;br /&gt;
 (downloads new image)&lt;br /&gt;
 docker images&lt;br /&gt;
 (shows two versions of mysql. old and new)&lt;br /&gt;
 docker stop some_container_name&lt;br /&gt;
 docker rmi -f cjklfs23404&lt;br /&gt;
 (where cjklfs23404 is the old container alias under docker images)&lt;br /&gt;
 docker-compose up -d mysql&lt;br /&gt;
&lt;br /&gt;
====Containers don't all Restart?!====&lt;br /&gt;
Make sure to have in your docker compose for each container a '''restart:always'''&lt;br /&gt;
Otherwise, a container won't necessarily start when docker is restarted.&lt;br /&gt;
&lt;br /&gt;
===Search for images===&lt;br /&gt;
 docker search &amp;lt;imagename&amp;gt;&lt;br /&gt;
====Search for Versions of an image====&lt;br /&gt;
What if you want to see what versions are available for a given image? Say you want php, but don't know which to get. hub.docker.com is broken. Requires js, slow, and bad. You can't get a list of images on it easily. &lt;br /&gt;
&lt;br /&gt;
Solution:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
#https://stackoverflow.com/questions/28320134/how-can-i-list-all-tags-for-a-docker-image-on-a-remote-registry&lt;br /&gt;
#$1 means&lt;br /&gt;
#first parameter you pass to this script will be searched&lt;br /&gt;
#e.g. working: debian&lt;br /&gt;
#note: some have multiple layers&lt;br /&gt;
#e.g. gitea/gitea is literally entered as $1 == gitea/gitea  (teste, working)&lt;br /&gt;
# while debian is just debian. so be aware.&lt;br /&gt;
&lt;br /&gt;
wget -q https://registry.hub.docker.com/v1/repositories/$1/tags -O -  \&lt;br /&gt;
| sed -e 's/[][]//g' -e 's/&amp;quot;//g' -e 's/ //g' | tr '}' '\n'  | awk -F: '{print $3}'&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Ref: https://stackoverflow.com/questions/54418542/dockerhub-listing-all-available-versions-of-a-given-image&lt;br /&gt;
&lt;br /&gt;
https://stackoverflow.com/questions/28320134/how-can-i-list-all-tags-for-a-docker-image-on-a-remote-registry&lt;br /&gt;
&lt;br /&gt;
===Save Changes to Docker Image===&lt;br /&gt;
 docker commit&lt;br /&gt;
See official documentation.&lt;br /&gt;
&lt;br /&gt;
==Dockerfile==&lt;br /&gt;
Dockerfiles and compose are slightly confusing. Sometimes you see images run an entrypoint script, sometimes not. In any case, Dockerfiles are fundamental to reproducible builds.&lt;br /&gt;
&lt;br /&gt;
Basic usage is:&lt;br /&gt;
* Docker-compose builds container from dockerfile (say you start with alpine, and install some programs)&lt;br /&gt;
* that container you built is used from thence on. &lt;br /&gt;
* if you want to change dockerfile, make changes and you must call docker-compose up --build otherwise, it will use the old container&lt;br /&gt;
&lt;br /&gt;
For a basic apache server, you might call the following in a cmd at the end of the dockerfile:&lt;br /&gt;
 CMD [&amp;quot;/usr/sbin/apache2&amp;quot;, &amp;quot;-D&amp;quot;, &amp;quot;FOREGROUND&amp;quot;]&lt;br /&gt;
When in doubt, work off of existing examples.&lt;br /&gt;
&lt;br /&gt;
==Volumes==&lt;br /&gt;
Volumes can be handled at least two ways. The simplest is to store files in a local directory which is then mapped to the remote drive.&lt;br /&gt;
&lt;br /&gt;
e.g. docker-compose:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  nginx:&lt;br /&gt;
    image: nginx:####&lt;br /&gt;
    container_name: mynginxserver&lt;br /&gt;
    volumes:&lt;br /&gt;
      - ./nginx.conf:/etc/nginx/nginx.conf&lt;br /&gt;
      - /etc/letsencrypt/:/etc/letsencrypt/&lt;br /&gt;
      - ./local_dir/:/var/www/html/&lt;br /&gt;
      - ./local_logs/:/var/log/nginx/&lt;br /&gt;
    ports:&lt;br /&gt;
      - 80:80&lt;br /&gt;
      - 443:443&lt;br /&gt;
    restart: always&lt;br /&gt;
    logging:&lt;br /&gt;
      driver: &amp;quot;json-file&amp;quot;&lt;br /&gt;
      options:&lt;br /&gt;
        max-size: &amp;quot;200k&amp;quot;&lt;br /&gt;
        max-file: &amp;quot;10&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Here, in the local dir where docker-compose is run, the ./local_dir/ or ./local_logs will store the containers html or logs respectively. Simple. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
However, if you just have a volume, without a local directory, then it will save in /var/ somewhere (unintuitive... bad).&lt;br /&gt;
e.g. from Dolibarr:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
The Dolibarr installation and all data beyond what lives in the database&lt;br /&gt;
 (file uploads, etc) are stored in the unnamed docker volume volume&lt;br /&gt;
/var/www/html and /var/www/documents. The docker daemon will store&lt;br /&gt;
 that data within the docker directory /var/lib/docker/volumes/....&lt;br /&gt;
That means your data is saved even if the container crashes, is stopped&lt;br /&gt;
or deleted.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Specific Tips==&lt;br /&gt;
===YAML is space sensitive===&lt;br /&gt;
When you edit the .yml file for docker-compose, you have to hit spaces in a certain pattern (tabs not allowed). This is absurd, but just be aware. The errors are cryptic, and its often just because the spacing doesn't stick to what it expects.&lt;br /&gt;
===If you restart a containers namesake process, it will probably restart / reset the container===&lt;br /&gt;
So if you are troubleshooting an apache container, you edit some files, then /etc/init.d/apache2 restart, uh oh... You just undid all the edits you made, if they aren't in a permanent volume. You can shell in, make edits, and then exit the shell, but a service restart often resets the container.&lt;br /&gt;
===Consider a single reverse proxy, to handle multiple websites===&lt;br /&gt;
There are many ways to do this. I use an nginx proxy from scratch. You can also use some containers that are built for this purpose (I personally think it's bloated but a lot of people use Jason Wilder's proxy)&lt;br /&gt;
https://web.archive.org/web/https://github.com/jwilder/nginx-proxy - A lot of people swear by this, but I think it's straying too far to the high level.&lt;br /&gt;
===If you use a single reverse proxy, Lets Encrypt can be done easy===&lt;br /&gt;
In this case scenario you would have certbot on the host and a local volume that the proxy has access to which is the webroot of the Lets Encrypt scripts. The nginx proxy entry look something like this:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
location ^~ /.well-known {&lt;br /&gt;
     alias /var/www/html/.well-known/;&lt;br /&gt;
      autoindex on;&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
And this is put in every server declaration of nginx.conf. Real simple, real easy. The docker compose of the nginx proxy is something like:&lt;br /&gt;
&lt;br /&gt;
{{cat|docker-compose.yml|&lt;br /&gt;
nginx:&lt;br /&gt;
    image: nginx:latest&lt;br /&gt;
    container_name: custom_name_for_my_proxy&lt;br /&gt;
    volumes:&lt;br /&gt;
      - ./nginx.conf:/etc/nginx/nginx.conf&lt;br /&gt;
      - /etc/letsencrypt/:/etc/letsencrypt/&lt;br /&gt;
      - ./webroot/:/var/www/html/&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
The volumes section is extremely simple, don't be scared. There are two entries. Local and remote. You specify what folder will be the local directory which will be cloned to the host at the remote path you specify. So, the host runs certbot at /etc/letsencrypt, and this folder is cloned to the nginx proxy container, at the same location. Finally, webroot must be set in certbot, but it prompts you for this. And if you forget or get it wrong, it can be configured somewhere in /etc/letsencrypt. it's a one liner text entry).&lt;br /&gt;
&lt;br /&gt;
===Give every Container a Containername===&lt;br /&gt;
This makes it easier to refer to them later. All you need to do in the compose file is include container\_name: something. Much better than the gibberish they give these names if you don't include it.&lt;br /&gt;
===Beware of Interrupting Initting Containers===&lt;br /&gt;
When you first build a container, it might take 30-60 or more seconds to do whatever it needs to do. If, before then, you restart it... It may get corrupted. This has happened to me more than once. When you are testing a new container, and it doesn't seem to work for some inexplicable reason, create a container with a new name (it will create a new one), or delete the first one, and start it again.&lt;br /&gt;
===Put Apache or Program logs from the Container in a volume that is locally accessible===&lt;br /&gt;
This means you want a volume something like ./containerA\_files/logs:/var/www/log/apache2/ so that you can monitor the logs from your host machine easily. docker logs doesn't have everything.&lt;br /&gt;
===Only Restart Containers you need to Restart===&lt;br /&gt;
You can restart everything with docker-compose restart, but it's faster, and less prone to break initting containers, if you docker restart containername. Do the latter.&lt;br /&gt;
===Volumes Mounting Over Existing Directories===&lt;br /&gt;
As discussed here: https://web.archive.org/web/https://github.com/moby/moby/issues/4361, if you add a volume to an existing container, it will seem to delete the folder's contents. I've seen mixed behaviour with this. Sometimes it deletes it even if you start a new container with the folder... Other times it has not. In any case, just docker cp the files to the folder, then add the volume mount. This may not be the most graceful solution for upgrades, but it will work. Best practices would be here (See: dbxt commented Dec 14, 2014): https://web.archive.org/web/https://github.com/docker-library/wordpress/issues/10&lt;br /&gt;
===If you edit a docker-compose file you must restart the container with Docker-compose===&lt;br /&gt;
If you make a change in docker compose, you must docker stop service, then docker-compose up -d service. Otherwise the changes will not take effect. The mistake here, would be thinking that you could just docker stop service, then docker start service... That doesn't work.&lt;br /&gt;
===Keep verbose logging off your HDD with RAM only logging===&lt;br /&gt;
If you have e.g. apache/nginx write to your HDD with every website visit, it will quickly wear out your HDD (esp. SSD). Put verbose logging in the RAM only with a tmpfs mount. https://docs.docker.com/storage/tmpfs/&lt;br /&gt;
&lt;br /&gt;
e.g. (ref: https://stackoverflow.com/questions/41902930/docker-compose-tmpfs-not-working)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
services:&lt;br /&gt;
  ubuntu:&lt;br /&gt;
    image: ubuntu&lt;br /&gt;
    command: &amp;quot;bash -c 'mount'&amp;quot;&lt;br /&gt;
    volumes:&lt;br /&gt;
      - cache_vol:/var/cache&lt;br /&gt;
      - run_vol:/run&lt;br /&gt;
&lt;br /&gt;
volumes:&lt;br /&gt;
  run_vol:&lt;br /&gt;
    driver_opts:&lt;br /&gt;
      type: tmpfs&lt;br /&gt;
      device: tmpfs&lt;br /&gt;
  cache_vol:&lt;br /&gt;
    driver_opts:&lt;br /&gt;
      type: tmpfs&lt;br /&gt;
      device: tmpfs&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This also allows you to share the tmpfs mounts if needed.&lt;br /&gt;
&lt;br /&gt;
Access it from host via:&lt;br /&gt;
 docker exec -it nginx_server tail -F /run/shm/access.log&lt;br /&gt;
Note that you might think you can do&lt;br /&gt;
 docker container run my_nginx_server tail -F /run/shm/access.log&lt;br /&gt;
But that will only work on container base images, not running containers. To 'execute' a command on a running or existing container, the command you want is exec. (Also used to interactively start bash shell above)&lt;br /&gt;
&lt;br /&gt;
EDIT: Use with discretion. Active data in RAM may use power.&lt;br /&gt;
&lt;br /&gt;
===Mysql Backup / Restore===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# Backup&lt;br /&gt;
docker exec CONTAINER /usr/bin/mysqldump -u root --password=root DATABASE &amp;gt; backup.sql&lt;br /&gt;
&lt;br /&gt;
# Restore&lt;br /&gt;
cat backup.sql | docker exec -i CONTAINER /usr/bin/mysql -u root --password=root DATABASE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
ref: https://gist.github.com/spalladino/6d981f7b33f6e0afe6bb&lt;br /&gt;
May not need to do this, if you keep the DB (ibdata files) in a local directory/volume via docker-compose.yml&lt;br /&gt;
e.g.&lt;br /&gt;
 mydb:&lt;br /&gt;
    image: mysql:9999&lt;br /&gt;
    volumes:&lt;br /&gt;
       - ./db_files:/var/lib/mysql&lt;br /&gt;
    restart: always&lt;br /&gt;
&lt;br /&gt;
===Limit docker logs===&lt;br /&gt;
Docker will keep lots of logs if you don't manage it.&lt;br /&gt;
https://github.com/docker/compose/issues/1083&lt;br /&gt;
https://docs.docker.com/compose/compose-file/#logging&lt;br /&gt;
https://stackoverflow.com/questions/31829587/docker-container-logs-taking-all-my-disk-space&lt;br /&gt;
view (all) logs with &lt;br /&gt;
 docker-compose logs&lt;br /&gt;
To limit a service's logs in docker-compose do the following:&lt;br /&gt;
* find a containers/services entry&lt;br /&gt;
* append to the end (watch the white space &amp;amp; no tabs)&lt;br /&gt;
     logging:&lt;br /&gt;
       driver: &amp;quot;json-file&amp;quot;&lt;br /&gt;
       options:&lt;br /&gt;
         max-size: &amp;quot;200k&amp;quot;&lt;br /&gt;
         max-file: &amp;quot;10&amp;quot;&lt;br /&gt;
The rule with logs, is nothing - unless you need it. Then everything. Any unnecessary logging is taxing the CPU / HDD.&lt;br /&gt;
Which leads me to...&lt;br /&gt;
&lt;br /&gt;
===view details about container===&lt;br /&gt;
To view paths, configuration settings, etc...&lt;br /&gt;
See&lt;br /&gt;
 docker inspect &amp;lt;name or id&amp;gt;&lt;br /&gt;
It's easier to grep these. the search in less wasn't working for me to find .LogPath for example.&lt;br /&gt;
 docker inspect mycontainer | grep log&lt;br /&gt;
Will show where the log files are located.&lt;br /&gt;
&lt;br /&gt;
===Installing Docker-compose from pip or github binary not Debian===&lt;br /&gt;
Subject. See official docker documentation which states the URL of&lt;br /&gt;
github.com/docker/compose/releases or pip.&lt;br /&gt;
&lt;br /&gt;
Pip is probably better.&lt;br /&gt;
 apt-get install python3-pip &lt;br /&gt;
 pip3 install docker-compose&lt;br /&gt;
&lt;br /&gt;
==Troubleshooting==&lt;br /&gt;
===Cannot start container: [0] Id already in use #20570===&lt;br /&gt;
* https://github.com/moby/moby/issues/20570&lt;br /&gt;
After update, unable to start container. Solution was found to be:&lt;br /&gt;
 docker-compose down -v then docker-compose up -d&lt;br /&gt;
Container was viewable with&lt;br /&gt;
 docker ps -a (not just docker ps)&lt;br /&gt;
==Poor Design==&lt;br /&gt;
===Creating a docker-compose with a stable or latest tag===&lt;br /&gt;
If you make a docker-compose file, you should link it to a marked version. You can later edit it, to use stable or latest, but one of the strengths of Docker is version control. If you create a docker-compose, always test on a specific version, should you need to roll back in the future. Otherwise, your scripts will fail in 2-20-200 years when the conf files are not supported anymore.&lt;br /&gt;
&lt;br /&gt;
e.g. https://github.com/nucreativa/frontaccounting-docker   (6th commit)&lt;br /&gt;
Here, the nginx config is no longer supported in vhosts, it must be in server_blocks. This would've been avoided by denoting a fixed nginx release instead of tag:latest.&lt;br /&gt;
&lt;br /&gt;
==See Also==&lt;br /&gt;
&lt;br /&gt;
* [[samba_docker_by_dlandon]]&lt;br /&gt;
&lt;br /&gt;
==External Links==&lt;br /&gt;
* https://github.com/LeCoupa/awesome-cheatsheets/blob/master/tools/docker.sh Information dense cheatsheet (unfortunately github)&lt;br /&gt;
* https://gist.github.com/spalladino/6d981f7b33f6e0afe6bb A million idiots type &amp;quot;thanks&amp;quot;. Also the source for the mysql backup command.&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
{{GNU\Linux}}&lt;/div&gt;</summary>
		<author><name>Adminguy</name></author>
	</entry>
	<entry>
		<id>http://steakwiki.com/index.php?title=Docker&amp;diff=977</id>
		<title>Docker</title>
		<link rel="alternate" type="text/html" href="http://steakwiki.com/index.php?title=Docker&amp;diff=977"/>
		<updated>2021-02-25T22:13:13Z</updated>

		<summary type="html">&lt;p&gt;Adminguy: /* Fails */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;small&amp;gt;Docker is a type of virtualization for Gnu\Linux that allows programs to run and share similar resources, without having a full OS for each image, but while still isolating each 'vm'.&lt;br /&gt;
&lt;br /&gt;
==General Tips==&lt;br /&gt;
It helps to read a book, and then keep it as a Reference. Here Using Docker By Adrian Mouat is a decent book. In fact, you should be reading books on any subject that interests you. Physical paper books, too.&lt;br /&gt;
&lt;br /&gt;
Docker is x86_64. ARM has a separate build. There is no i386.&lt;br /&gt;
&lt;br /&gt;
You will want 'some' RAM. I had 1GB on a P4 machine, and that was not enough. 4GB was enough. &lt;br /&gt;
&lt;br /&gt;
You should always use docker compose. Docker is possible to run on the command line, but with a compose file, you can write everything down in a much simpler fashion. Use compose. It's a separate install, currently. Install it. ''Seriously, just ignore the docker command lines. I consider them useless. More of a red herring for rookies.''&lt;br /&gt;
&lt;br /&gt;
===ARM is SOL===&lt;br /&gt;
I tried to use Docker on ARM, and while you might be able to install docker, you will find that images for your applications may not be there. e.g. you will find Nginx, but you won't find Gitlab. This means that docker is pretty much x86-64 only.&lt;br /&gt;
&lt;br /&gt;
==Docker Commands==&lt;br /&gt;
Here are commands you need to know. Just the necessary ones.&lt;br /&gt;
{{cmd| docker-compose up -d}} &lt;br /&gt;
 &lt;br /&gt;
Starts the containers in the docker compose file, if they aren't already started. the -d detaches from the stdout logging. You don't need to use stdout logging, you can use docker logs, but its there if you want it.&lt;br /&gt;
 {{cmd| docker ps }}&lt;br /&gt;
Lists containers running. If one fails to start, you'll see it missing from here&lt;br /&gt;
 {{cmd|docker logs &amp;lt;containername&amp;gt; }}&lt;br /&gt;
Gives you some logging output from the container. Often enough to troubleshoot. (also see tips below).&lt;br /&gt;
 {{cmd|docker exec -it &amp;lt;containername&amp;gt; /bin/bash}}&lt;br /&gt;
This will get you in a shell in the docker container. From here you can do what you need to. Most are debian, and need apt-get install less nano or whatever program you are missing. Ping is missing from possibly all containers, so if you want to test via ping, you'll have to apt-get it.&lt;br /&gt;
 {{cmd|docker-compose restart }}&lt;br /&gt;
This will restart all containers. However, I don't recommend it. Initting containers can get corrupted this way, and also its much easier to restart a single faulty container via...&lt;br /&gt;
 {{cmd|docker restart &amp;lt;containername&amp;gt; }}&lt;br /&gt;
This will restart one single container.&lt;br /&gt;
 {{cmd|docker cp &amp;lt;containername&amp;gt;:/dir/to/file dest }}&lt;br /&gt;
You can copy files from local machine to docker, or vice versa with this. Extremely useful.&lt;br /&gt;
&lt;br /&gt;
===Deleting Containers===&lt;br /&gt;
Less often, you might want to know &lt;br /&gt;
{{cmd|&lt;br /&gt;
 #!/bin/bash&lt;br /&gt;
 docker rm $(docker ps -a -q)&lt;br /&gt;
 docker rmi $(docker images -q) --force}}&lt;br /&gt;
&lt;br /&gt;
This starts over from scratch. This is how easy it is to reboot a docker from square one.  note: below command (rmi), only needed if you want to remove base images. Needed when updating a stable. Not needed when changing other parameters not related to base image. Also, this deletes all containers, which maybe you don't want to do, if you either A) only want to delete certain images you are testing B) have some containers with custom changes saved, and not backed up elsewhere.&lt;br /&gt;
&lt;br /&gt;
===Updating===&lt;br /&gt;
 docker images&lt;br /&gt;
 (shows out of date image)&lt;br /&gt;
 docker pull mysql&lt;br /&gt;
 (downloads new image)&lt;br /&gt;
 docker images&lt;br /&gt;
 (shows two versions of mysql. old and new)&lt;br /&gt;
 docker stop some_container_name&lt;br /&gt;
 docker rmi -f cjklfs23404&lt;br /&gt;
 (where cjklfs23404 is the old container alias under docker images)&lt;br /&gt;
 docker-compose up -d mysql&lt;br /&gt;
&lt;br /&gt;
====Containers don't all Restart?!====&lt;br /&gt;
Make sure to have in your docker compose for each container a '''restart:always'''&lt;br /&gt;
Otherwise, a container won't necessarily start when docker is restarted.&lt;br /&gt;
&lt;br /&gt;
===Search for images===&lt;br /&gt;
 docker search &amp;lt;imagename&amp;gt;&lt;br /&gt;
====Search for Versions of an image====&lt;br /&gt;
What if you want to see what versions are available for a given image? Say you want php, but don't know which to get. hub.docker.com is broken. Requires js, slow, and bad. You can't get a list of images on it easily. &lt;br /&gt;
&lt;br /&gt;
Solution:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
#https://stackoverflow.com/questions/28320134/how-can-i-list-all-tags-for-a-docker-image-on-a-remote-registry&lt;br /&gt;
#$1 means&lt;br /&gt;
#first parameter you pass to this script will be searched&lt;br /&gt;
#e.g. working: debian&lt;br /&gt;
#note: some have multiple layers&lt;br /&gt;
#e.g. gitea/gitea is literally entered as $1 == gitea/gitea  (teste, working)&lt;br /&gt;
# while debian is just debian. so be aware.&lt;br /&gt;
&lt;br /&gt;
wget -q https://registry.hub.docker.com/v1/repositories/$1/tags -O -  \&lt;br /&gt;
| sed -e 's/[][]//g' -e 's/&amp;quot;//g' -e 's/ //g' | tr '}' '\n'  | awk -F: '{print $3}'&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Ref: https://stackoverflow.com/questions/54418542/dockerhub-listing-all-available-versions-of-a-given-image&lt;br /&gt;
&lt;br /&gt;
https://stackoverflow.com/questions/28320134/how-can-i-list-all-tags-for-a-docker-image-on-a-remote-registry&lt;br /&gt;
&lt;br /&gt;
===Save Changes to Docker Image===&lt;br /&gt;
 docker commit&lt;br /&gt;
See official documentation.&lt;br /&gt;
&lt;br /&gt;
==Dockerfile==&lt;br /&gt;
Dockerfiles and compose are slightly confusing. Sometimes you see images run an entrypoint script, sometimes not. In any case, Dockerfiles are fundamental to reproducible builds.&lt;br /&gt;
&lt;br /&gt;
Basic usage is:&lt;br /&gt;
* Docker-compose builds container from dockerfile (say you start with alpine, and install some programs)&lt;br /&gt;
* that container you built is used from thence on. &lt;br /&gt;
* if you want to change dockerfile, make changes and you must call docker-compose up --build otherwise, it will use the old container&lt;br /&gt;
&lt;br /&gt;
For a basic apache server, you might call the following in a cmd at the end of the dockerfile:&lt;br /&gt;
 CMD [&amp;quot;/usr/sbin/apache2&amp;quot;, &amp;quot;-D&amp;quot;, &amp;quot;FOREGROUND&amp;quot;]&lt;br /&gt;
When in doubt, work off of existing examples.&lt;br /&gt;
&lt;br /&gt;
==Volumes==&lt;br /&gt;
Volumes can be handled at least two ways. The simplest is to store files in a local directory which is then mapped to the remote drive.&lt;br /&gt;
&lt;br /&gt;
e.g. docker-compose:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  nginx:&lt;br /&gt;
    image: nginx:####&lt;br /&gt;
    container_name: mynginxserver&lt;br /&gt;
    volumes:&lt;br /&gt;
      - ./nginx.conf:/etc/nginx/nginx.conf&lt;br /&gt;
      - /etc/letsencrypt/:/etc/letsencrypt/&lt;br /&gt;
      - ./local_dir/:/var/www/html/&lt;br /&gt;
      - ./local_logs/:/var/log/nginx/&lt;br /&gt;
    ports:&lt;br /&gt;
      - 80:80&lt;br /&gt;
      - 443:443&lt;br /&gt;
    restart: always&lt;br /&gt;
    logging:&lt;br /&gt;
      driver: &amp;quot;json-file&amp;quot;&lt;br /&gt;
      options:&lt;br /&gt;
        max-size: &amp;quot;200k&amp;quot;&lt;br /&gt;
        max-file: &amp;quot;10&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Here, in the local dir where docker-compose is run, the ./local_dir/ or ./local_logs will store the containers html or logs respectively. Simple. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
However, if you just have a volume, without a local directory, then it will save in /var/ somewhere (unintuitive... bad).&lt;br /&gt;
e.g. from Dolibarr:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
The Dolibarr installation and all data beyond what lives in the database&lt;br /&gt;
 (file uploads, etc) are stored in the unnamed docker volume volume&lt;br /&gt;
/var/www/html and /var/www/documents. The docker daemon will store&lt;br /&gt;
 that data within the docker directory /var/lib/docker/volumes/....&lt;br /&gt;
That means your data is saved even if the container crashes, is stopped&lt;br /&gt;
or deleted.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Specific Tips==&lt;br /&gt;
===YAML is space sensitive===&lt;br /&gt;
When you edit the .yml file for docker-compose, you have to hit spaces in a certain pattern (tabs not allowed). This is absurd, but just be aware. The errors are cryptic, and its often just because the spacing doesn't stick to what it expects.&lt;br /&gt;
===If you restart a containers namesake process, it will probably restart / reset the container===&lt;br /&gt;
So if you are troubleshooting an apache container, you edit some files, then /etc/init.d/apache2 restart, uh oh... You just undid all the edits you made, if they aren't in a permanent volume. You can shell in, make edits, and then exit the shell, but a service restart often resets the container.&lt;br /&gt;
===Consider a single reverse proxy, to handle multiple websites===&lt;br /&gt;
There are many ways to do this. I use an nginx proxy from scratch. You can also use some containers that are built for this purpose (I personally think it's bloated but a lot of people use Jason Wilder's proxy)&lt;br /&gt;
https://web.archive.org/web/https://github.com/jwilder/nginx-proxy - A lot of people swear by this, but I think it's straying too far to the high level.&lt;br /&gt;
===If you use a single reverse proxy, Lets Encrypt can be done easy===&lt;br /&gt;
In this case scenario you would have certbot on the host and a local volume that the proxy has access to which is the webroot of the Lets Encrypt scripts. The nginx proxy entry look something like this:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
location ^~ /.well-known {&lt;br /&gt;
     alias /var/www/html/.well-known/;&lt;br /&gt;
      autoindex on;&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
And this is put in every server declaration of nginx.conf. Real simple, real easy. The docker compose of the nginx proxy is something like:&lt;br /&gt;
&lt;br /&gt;
{{cat|docker-compose.yml|&lt;br /&gt;
nginx:&lt;br /&gt;
    image: nginx:latest&lt;br /&gt;
    container_name: custom_name_for_my_proxy&lt;br /&gt;
    volumes:&lt;br /&gt;
      - ./nginx.conf:/etc/nginx/nginx.conf&lt;br /&gt;
      - /etc/letsencrypt/:/etc/letsencrypt/&lt;br /&gt;
      - ./webroot/:/var/www/html/&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
The volumes section is extremely simple, don't be scared. There are two entries. Local and remote. You specify what folder will be the local directory which will be cloned to the host at the remote path you specify. So, the host runs certbot at /etc/letsencrypt, and this folder is cloned to the nginx proxy container, at the same location. Finally, webroot must be set in certbot, but it prompts you for this. And if you forget or get it wrong, it can be configured somewhere in /etc/letsencrypt. it's a one liner text entry).&lt;br /&gt;
&lt;br /&gt;
===Give every Container a Containername===&lt;br /&gt;
This makes it easier to refer to them later. All you need to do in the compose file is include container\_name: something. Much better than the gibberish they give these names if you don't include it.&lt;br /&gt;
===Beware of Interrupting Initting Containers===&lt;br /&gt;
When you first build a container, it might take 30-60 or more seconds to do whatever it needs to do. If, before then, you restart it... It may get corrupted. This has happened to me more than once. When you are testing a new container, and it doesn't seem to work for some inexplicable reason, create a container with a new name (it will create a new one), or delete the first one, and start it again.&lt;br /&gt;
===Put Apache or Program logs from the Container in a volume that is locally accessible===&lt;br /&gt;
This means you want a volume something like ./containerA\_files/logs:/var/www/log/apache2/ so that you can monitor the logs from your host machine easily. docker logs doesn't have everything.&lt;br /&gt;
===Only Restart Containers you need to Restart===&lt;br /&gt;
You can restart everything with docker-compose restart, but it's faster, and less prone to break initting containers, if you docker restart containername. Do the latter.&lt;br /&gt;
===Volumes Mounting Over Existing Directories===&lt;br /&gt;
As discussed here: https://web.archive.org/web/https://github.com/moby/moby/issues/4361, if you add a volume to an existing container, it will seem to delete the folder's contents. I've seen mixed behaviour with this. Sometimes it deletes it even if you start a new container with the folder... Other times it has not. In any case, just docker cp the files to the folder, then add the volume mount. This may not be the most graceful solution for upgrades, but it will work. Best practices would be here (See: dbxt commented Dec 14, 2014): https://web.archive.org/web/https://github.com/docker-library/wordpress/issues/10&lt;br /&gt;
===If you edit a docker-compose file you must restart the container with Docker-compose===&lt;br /&gt;
If you make a change in docker compose, you must docker stop service, then docker-compose up -d service. Otherwise the changes will not take effect. The mistake here, would be thinking that you could just docker stop service, then docker start service... That doesn't work.&lt;br /&gt;
===Keep verbose logging off your HDD with RAM only logging===&lt;br /&gt;
If you have e.g. apache/nginx write to your HDD with every website visit, it will quickly wear out your HDD (esp. SSD). Put verbose logging in the RAM only with a tmpfs mount. https://docs.docker.com/storage/tmpfs/&lt;br /&gt;
&lt;br /&gt;
e.g. (ref: https://stackoverflow.com/questions/41902930/docker-compose-tmpfs-not-working)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
services:&lt;br /&gt;
  ubuntu:&lt;br /&gt;
    image: ubuntu&lt;br /&gt;
    command: &amp;quot;bash -c 'mount'&amp;quot;&lt;br /&gt;
    volumes:&lt;br /&gt;
      - cache_vol:/var/cache&lt;br /&gt;
      - run_vol:/run&lt;br /&gt;
&lt;br /&gt;
volumes:&lt;br /&gt;
  run_vol:&lt;br /&gt;
    driver_opts:&lt;br /&gt;
      type: tmpfs&lt;br /&gt;
      device: tmpfs&lt;br /&gt;
  cache_vol:&lt;br /&gt;
    driver_opts:&lt;br /&gt;
      type: tmpfs&lt;br /&gt;
      device: tmpfs&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This also allows you to share the tmpfs mounts if needed.&lt;br /&gt;
&lt;br /&gt;
Access it from host via:&lt;br /&gt;
 docker exec -it nginx_server tail -F /run/shm/access.log&lt;br /&gt;
Note that you might think you can do&lt;br /&gt;
 docker container run my_nginx_server tail -F /run/shm/access.log&lt;br /&gt;
But that will only work on container base images, not running containers. To 'execute' a command on a running or existing container, the command you want is exec. (Also used to interactively start bash shell above)&lt;br /&gt;
&lt;br /&gt;
EDIT: Use with discretion. Active data in RAM may use power.&lt;br /&gt;
&lt;br /&gt;
===Mysql Backup / Restore===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# Backup&lt;br /&gt;
docker exec CONTAINER /usr/bin/mysqldump -u root --password=root DATABASE &amp;gt; backup.sql&lt;br /&gt;
&lt;br /&gt;
# Restore&lt;br /&gt;
cat backup.sql | docker exec -i CONTAINER /usr/bin/mysql -u root --password=root DATABASE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
ref: https://gist.github.com/spalladino/6d981f7b33f6e0afe6bb&lt;br /&gt;
May not need to do this, if you keep the DB (ibdata files) in a local directory/volume via docker-compose.yml&lt;br /&gt;
e.g.&lt;br /&gt;
 mydb:&lt;br /&gt;
    image: mysql:9999&lt;br /&gt;
    volumes:&lt;br /&gt;
       - ./db_files:/var/lib/mysql&lt;br /&gt;
    restart: always&lt;br /&gt;
&lt;br /&gt;
===Limit docker logs===&lt;br /&gt;
Docker will keep lots of logs if you don't manage it.&lt;br /&gt;
https://github.com/docker/compose/issues/1083&lt;br /&gt;
https://docs.docker.com/compose/compose-file/#logging&lt;br /&gt;
https://stackoverflow.com/questions/31829587/docker-container-logs-taking-all-my-disk-space&lt;br /&gt;
view (all) logs with &lt;br /&gt;
 docker-compose logs&lt;br /&gt;
To limit a service's logs in docker-compose do the following:&lt;br /&gt;
* find a containers/services entry&lt;br /&gt;
* append to the end (watch the white space &amp;amp; no tabs)&lt;br /&gt;
     logging:&lt;br /&gt;
       driver: &amp;quot;json-file&amp;quot;&lt;br /&gt;
       options:&lt;br /&gt;
         max-size: &amp;quot;200k&amp;quot;&lt;br /&gt;
         max-file: &amp;quot;10&amp;quot;&lt;br /&gt;
The rule with logs, is nothing - unless you need it. Then everything. Any unnecessary logging is taxing the CPU / HDD.&lt;br /&gt;
Which leads me to...&lt;br /&gt;
&lt;br /&gt;
===view details about container===&lt;br /&gt;
To view paths, configuration settings, etc...&lt;br /&gt;
See&lt;br /&gt;
 docker inspect &amp;lt;name or id&amp;gt;&lt;br /&gt;
It's easier to grep these. the search in less wasn't working for me to find .LogPath for example.&lt;br /&gt;
 docker inspect mycontainer | grep log&lt;br /&gt;
Will show where the log files are located.&lt;br /&gt;
&lt;br /&gt;
===Installing Docker-compose from pip or github binary not Debian===&lt;br /&gt;
Subject. See official docker documentation which states the URL of&lt;br /&gt;
github.com/docker/compose/releases or pip.&lt;br /&gt;
&lt;br /&gt;
Pip is probably better.&lt;br /&gt;
 apt-get install python3-pip &lt;br /&gt;
 pip3 install docker-compose&lt;br /&gt;
&lt;br /&gt;
==Troubleshooting==&lt;br /&gt;
===Cannot start container: [0] Id already in use #20570===&lt;br /&gt;
* https://github.com/moby/moby/issues/20570&lt;br /&gt;
After update, unable to start container. Solution was found to be:&lt;br /&gt;
 docker-compose down -v then docker-compose up -d&lt;br /&gt;
Container was viewable with&lt;br /&gt;
 docker ps -a (not just docker ps)&lt;br /&gt;
==Poor Design==&lt;br /&gt;
===Creating a docker-compose with a stable or latest tag===&lt;br /&gt;
If you make a docker-compose file, you must link it to a marked version. You can later edit it, to use stable or latest, but one of the strengths of Docker is version control. If you create a docker-compose, always test on a specific version, should you need to roll back in the future. Otherwise, your scripts will fail in 2-20-200 years when the conf files are not supported anymore.&lt;br /&gt;
&lt;br /&gt;
e.g. https://github.com/nucreativa/frontaccounting-docker   (6th commit)&lt;br /&gt;
Here, the nginx config is no longer supported in vhosts, it must be in server_blocks. This would've been avoided by denoting a fixed nginx release instead of tag:latest.&lt;br /&gt;
&lt;br /&gt;
==See Also==&lt;br /&gt;
&lt;br /&gt;
* [[samba_docker_by_dlandon]]&lt;br /&gt;
&lt;br /&gt;
==External Links==&lt;br /&gt;
* https://github.com/LeCoupa/awesome-cheatsheets/blob/master/tools/docker.sh Information dense cheatsheet (unfortunately github)&lt;br /&gt;
* https://gist.github.com/spalladino/6d981f7b33f6e0afe6bb A million idiots type &amp;quot;thanks&amp;quot;. Also the source for the mysql backup command.&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
{{GNU\Linux}}&lt;/div&gt;</summary>
		<author><name>Adminguy</name></author>
	</entry>
	<entry>
		<id>http://steakwiki.com/index.php?title=Docker&amp;diff=976</id>
		<title>Docker</title>
		<link rel="alternate" type="text/html" href="http://steakwiki.com/index.php?title=Docker&amp;diff=976"/>
		<updated>2021-02-25T22:05:02Z</updated>

		<summary type="html">&lt;p&gt;Adminguy: /* Dockerfile */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;small&amp;gt;Docker is a type of virtualization for Gnu\Linux that allows programs to run and share similar resources, without having a full OS for each image, but while still isolating each 'vm'.&lt;br /&gt;
&lt;br /&gt;
==General Tips==&lt;br /&gt;
It helps to read a book, and then keep it as a Reference. Here Using Docker By Adrian Mouat is a decent book. In fact, you should be reading books on any subject that interests you. Physical paper books, too.&lt;br /&gt;
&lt;br /&gt;
Docker is x86_64. ARM has a separate build. There is no i386.&lt;br /&gt;
&lt;br /&gt;
You will want 'some' RAM. I had 1GB on a P4 machine, and that was not enough. 4GB was enough. &lt;br /&gt;
&lt;br /&gt;
You should always use docker compose. Docker is possible to run on the command line, but with a compose file, you can write everything down in a much simpler fashion. Use compose. It's a separate install, currently. Install it. ''Seriously, just ignore the docker command lines. I consider them useless. More of a red herring for rookies.''&lt;br /&gt;
&lt;br /&gt;
===ARM is SOL===&lt;br /&gt;
I tried to use Docker on ARM, and while you might be able to install docker, you will find that images for your applications may not be there. e.g. you will find Nginx, but you won't find Gitlab. This means that docker is pretty much x86-64 only.&lt;br /&gt;
&lt;br /&gt;
==Docker Commands==&lt;br /&gt;
Here are commands you need to know. Just the necessary ones.&lt;br /&gt;
{{cmd| docker-compose up -d}} &lt;br /&gt;
 &lt;br /&gt;
Starts the containers in the docker compose file, if they aren't already started. the -d detaches from the stdout logging. You don't need to use stdout logging, you can use docker logs, but its there if you want it.&lt;br /&gt;
 {{cmd| docker ps }}&lt;br /&gt;
Lists containers running. If one fails to start, you'll see it missing from here&lt;br /&gt;
 {{cmd|docker logs &amp;lt;containername&amp;gt; }}&lt;br /&gt;
Gives you some logging output from the container. Often enough to troubleshoot. (also see tips below).&lt;br /&gt;
 {{cmd|docker exec -it &amp;lt;containername&amp;gt; /bin/bash}}&lt;br /&gt;
This will get you in a shell in the docker container. From here you can do what you need to. Most are debian, and need apt-get install less nano or whatever program you are missing. Ping is missing from possibly all containers, so if you want to test via ping, you'll have to apt-get it.&lt;br /&gt;
 {{cmd|docker-compose restart }}&lt;br /&gt;
This will restart all containers. However, I don't recommend it. Initting containers can get corrupted this way, and also its much easier to restart a single faulty container via...&lt;br /&gt;
 {{cmd|docker restart &amp;lt;containername&amp;gt; }}&lt;br /&gt;
This will restart one single container.&lt;br /&gt;
 {{cmd|docker cp &amp;lt;containername&amp;gt;:/dir/to/file dest }}&lt;br /&gt;
You can copy files from local machine to docker, or vice versa with this. Extremely useful.&lt;br /&gt;
&lt;br /&gt;
===Deleting Containers===&lt;br /&gt;
Less often, you might want to know &lt;br /&gt;
{{cmd|&lt;br /&gt;
 #!/bin/bash&lt;br /&gt;
 docker rm $(docker ps -a -q)&lt;br /&gt;
 docker rmi $(docker images -q) --force}}&lt;br /&gt;
&lt;br /&gt;
This starts over from scratch. This is how easy it is to reboot a docker from square one.  note: below command (rmi), only needed if you want to remove base images. Needed when updating a stable. Not needed when changing other parameters not related to base image. Also, this deletes all containers, which maybe you don't want to do, if you either A) only want to delete certain images you are testing B) have some containers with custom changes saved, and not backed up elsewhere.&lt;br /&gt;
&lt;br /&gt;
===Updating===&lt;br /&gt;
 docker images&lt;br /&gt;
 (shows out of date image)&lt;br /&gt;
 docker pull mysql&lt;br /&gt;
 (downloads new image)&lt;br /&gt;
 docker images&lt;br /&gt;
 (shows two versions of mysql. old and new)&lt;br /&gt;
 docker stop some_container_name&lt;br /&gt;
 docker rmi -f cjklfs23404&lt;br /&gt;
 (where cjklfs23404 is the old container alias under docker images)&lt;br /&gt;
 docker-compose up -d mysql&lt;br /&gt;
&lt;br /&gt;
====Containers don't all Restart?!====&lt;br /&gt;
Make sure to have in your docker compose for each container a '''restart:always'''&lt;br /&gt;
Otherwise, a container won't necessarily start when docker is restarted.&lt;br /&gt;
&lt;br /&gt;
===Search for images===&lt;br /&gt;
 docker search &amp;lt;imagename&amp;gt;&lt;br /&gt;
====Search for Versions of an image====&lt;br /&gt;
What if you want to see what versions are available for a given image? Say you want php, but don't know which to get. hub.docker.com is broken. Requires js, slow, and bad. You can't get a list of images on it easily. &lt;br /&gt;
&lt;br /&gt;
Solution:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
#https://stackoverflow.com/questions/28320134/how-can-i-list-all-tags-for-a-docker-image-on-a-remote-registry&lt;br /&gt;
#$1 means&lt;br /&gt;
#first parameter you pass to this script will be searched&lt;br /&gt;
#e.g. working: debian&lt;br /&gt;
#note: some have multiple layers&lt;br /&gt;
#e.g. gitea/gitea is literally entered as $1 == gitea/gitea  (teste, working)&lt;br /&gt;
# while debian is just debian. so be aware.&lt;br /&gt;
&lt;br /&gt;
wget -q https://registry.hub.docker.com/v1/repositories/$1/tags -O -  \&lt;br /&gt;
| sed -e 's/[][]//g' -e 's/&amp;quot;//g' -e 's/ //g' | tr '}' '\n'  | awk -F: '{print $3}'&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Ref: https://stackoverflow.com/questions/54418542/dockerhub-listing-all-available-versions-of-a-given-image&lt;br /&gt;
&lt;br /&gt;
https://stackoverflow.com/questions/28320134/how-can-i-list-all-tags-for-a-docker-image-on-a-remote-registry&lt;br /&gt;
&lt;br /&gt;
===Save Changes to Docker Image===&lt;br /&gt;
 docker commit&lt;br /&gt;
See official documentation.&lt;br /&gt;
&lt;br /&gt;
==Dockerfile==&lt;br /&gt;
Dockerfiles and compose are slightly confusing. Sometimes you see images run an entrypoint script, sometimes not. In any case, Dockerfiles are fundamental to reproducible builds.&lt;br /&gt;
&lt;br /&gt;
Basic usage is:&lt;br /&gt;
* Docker-compose builds container from dockerfile (say you start with alpine, and install some programs)&lt;br /&gt;
* that container you built is used from thence on. &lt;br /&gt;
* if you want to change dockerfile, make changes and you must call docker-compose up --build otherwise, it will use the old container&lt;br /&gt;
&lt;br /&gt;
For a basic apache server, you might call the following in a cmd at the end of the dockerfile:&lt;br /&gt;
 CMD [&amp;quot;/usr/sbin/apache2&amp;quot;, &amp;quot;-D&amp;quot;, &amp;quot;FOREGROUND&amp;quot;]&lt;br /&gt;
When in doubt, work off of existing examples.&lt;br /&gt;
&lt;br /&gt;
==Volumes==&lt;br /&gt;
Volumes can be handled at least two ways. The simplest is to store files in a local directory which is then mapped to the remote drive.&lt;br /&gt;
&lt;br /&gt;
e.g. docker-compose:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  nginx:&lt;br /&gt;
    image: nginx:####&lt;br /&gt;
    container_name: mynginxserver&lt;br /&gt;
    volumes:&lt;br /&gt;
      - ./nginx.conf:/etc/nginx/nginx.conf&lt;br /&gt;
      - /etc/letsencrypt/:/etc/letsencrypt/&lt;br /&gt;
      - ./local_dir/:/var/www/html/&lt;br /&gt;
      - ./local_logs/:/var/log/nginx/&lt;br /&gt;
    ports:&lt;br /&gt;
      - 80:80&lt;br /&gt;
      - 443:443&lt;br /&gt;
    restart: always&lt;br /&gt;
    logging:&lt;br /&gt;
      driver: &amp;quot;json-file&amp;quot;&lt;br /&gt;
      options:&lt;br /&gt;
        max-size: &amp;quot;200k&amp;quot;&lt;br /&gt;
        max-file: &amp;quot;10&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Here, in the local dir where docker-compose is run, the ./local_dir/ or ./local_logs will store the containers html or logs respectively. Simple. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
However, if you just have a volume, without a local directory, then it will save in /var/ somewhere (unintuitive... bad).&lt;br /&gt;
e.g. from Dolibarr:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
The Dolibarr installation and all data beyond what lives in the database&lt;br /&gt;
 (file uploads, etc) are stored in the unnamed docker volume volume&lt;br /&gt;
/var/www/html and /var/www/documents. The docker daemon will store&lt;br /&gt;
 that data within the docker directory /var/lib/docker/volumes/....&lt;br /&gt;
That means your data is saved even if the container crashes, is stopped&lt;br /&gt;
or deleted.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Specific Tips==&lt;br /&gt;
===YAML is space sensitive===&lt;br /&gt;
When you edit the .yml file for docker-compose, you have to hit spaces in a certain pattern (tabs not allowed). This is absurd, but just be aware. The errors are cryptic, and its often just because the spacing doesn't stick to what it expects.&lt;br /&gt;
===If you restart a containers namesake process, it will probably restart / reset the container===&lt;br /&gt;
So if you are troubleshooting an apache container, you edit some files, then /etc/init.d/apache2 restart, uh oh... You just undid all the edits you made, if they aren't in a permanent volume. You can shell in, make edits, and then exit the shell, but a service restart often resets the container.&lt;br /&gt;
===Consider a single reverse proxy, to handle multiple websites===&lt;br /&gt;
There are many ways to do this. I use an nginx proxy from scratch. You can also use some containers that are built for this purpose (I personally think it's bloated but a lot of people use Jason Wilder's proxy)&lt;br /&gt;
https://web.archive.org/web/https://github.com/jwilder/nginx-proxy - A lot of people swear by this, but I think it's straying too far to the high level.&lt;br /&gt;
===If you use a single reverse proxy, Lets Encrypt can be done easy===&lt;br /&gt;
In this case scenario you would have certbot on the host and a local volume that the proxy has access to which is the webroot of the Lets Encrypt scripts. The nginx proxy entry look something like this:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
location ^~ /.well-known {&lt;br /&gt;
     alias /var/www/html/.well-known/;&lt;br /&gt;
      autoindex on;&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
And this is put in every server declaration of nginx.conf. Real simple, real easy. The docker compose of the nginx proxy is something like:&lt;br /&gt;
&lt;br /&gt;
{{cat|docker-compose.yml|&lt;br /&gt;
nginx:&lt;br /&gt;
    image: nginx:latest&lt;br /&gt;
    container_name: custom_name_for_my_proxy&lt;br /&gt;
    volumes:&lt;br /&gt;
      - ./nginx.conf:/etc/nginx/nginx.conf&lt;br /&gt;
      - /etc/letsencrypt/:/etc/letsencrypt/&lt;br /&gt;
      - ./webroot/:/var/www/html/&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
The volumes section is extremely simple, don't be scared. There are two entries. Local and remote. You specify what folder will be the local directory which will be cloned to the host at the remote path you specify. So, the host runs certbot at /etc/letsencrypt, and this folder is cloned to the nginx proxy container, at the same location. Finally, webroot must be set in certbot, but it prompts you for this. And if you forget or get it wrong, it can be configured somewhere in /etc/letsencrypt. it's a one liner text entry).&lt;br /&gt;
&lt;br /&gt;
===Give every Container a Containername===&lt;br /&gt;
This makes it easier to refer to them later. All you need to do in the compose file is include container\_name: something. Much better than the gibberish they give these names if you don't include it.&lt;br /&gt;
===Beware of Interrupting Initting Containers===&lt;br /&gt;
When you first build a container, it might take 30-60 or more seconds to do whatever it needs to do. If, before then, you restart it... It may get corrupted. This has happened to me more than once. When you are testing a new container, and it doesn't seem to work for some inexplicable reason, create a container with a new name (it will create a new one), or delete the first one, and start it again.&lt;br /&gt;
===Put Apache or Program logs from the Container in a volume that is locally accessible===&lt;br /&gt;
This means you want a volume something like ./containerA\_files/logs:/var/www/log/apache2/ so that you can monitor the logs from your host machine easily. docker logs doesn't have everything.&lt;br /&gt;
===Only Restart Containers you need to Restart===&lt;br /&gt;
You can restart everything with docker-compose restart, but it's faster, and less prone to break initting containers, if you docker restart containername. Do the latter.&lt;br /&gt;
===Volumes Mounting Over Existing Directories===&lt;br /&gt;
As discussed here: https://web.archive.org/web/https://github.com/moby/moby/issues/4361, if you add a volume to an existing container, it will seem to delete the folder's contents. I've seen mixed behaviour with this. Sometimes it deletes it even if you start a new container with the folder... Other times it has not. In any case, just docker cp the files to the folder, then add the volume mount. This may not be the most graceful solution for upgrades, but it will work. Best practices would be here (See: dbxt commented Dec 14, 2014): https://web.archive.org/web/https://github.com/docker-library/wordpress/issues/10&lt;br /&gt;
===If you edit a docker-compose file you must restart the container with Docker-compose===&lt;br /&gt;
If you make a change in docker compose, you must docker stop service, then docker-compose up -d service. Otherwise the changes will not take effect. The mistake here, would be thinking that you could just docker stop service, then docker start service... That doesn't work.&lt;br /&gt;
===Keep verbose logging off your HDD with RAM only logging===&lt;br /&gt;
If you have e.g. apache/nginx write to your HDD with every website visit, it will quickly wear out your HDD (esp. SSD). Put verbose logging in the RAM only with a tmpfs mount. https://docs.docker.com/storage/tmpfs/&lt;br /&gt;
&lt;br /&gt;
e.g. (ref: https://stackoverflow.com/questions/41902930/docker-compose-tmpfs-not-working)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
services:&lt;br /&gt;
  ubuntu:&lt;br /&gt;
    image: ubuntu&lt;br /&gt;
    command: &amp;quot;bash -c 'mount'&amp;quot;&lt;br /&gt;
    volumes:&lt;br /&gt;
      - cache_vol:/var/cache&lt;br /&gt;
      - run_vol:/run&lt;br /&gt;
&lt;br /&gt;
volumes:&lt;br /&gt;
  run_vol:&lt;br /&gt;
    driver_opts:&lt;br /&gt;
      type: tmpfs&lt;br /&gt;
      device: tmpfs&lt;br /&gt;
  cache_vol:&lt;br /&gt;
    driver_opts:&lt;br /&gt;
      type: tmpfs&lt;br /&gt;
      device: tmpfs&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This also allows you to share the tmpfs mounts if needed.&lt;br /&gt;
&lt;br /&gt;
Access it from host via:&lt;br /&gt;
 docker exec -it nginx_server tail -F /run/shm/access.log&lt;br /&gt;
Note that you might think you can do&lt;br /&gt;
 docker container run my_nginx_server tail -F /run/shm/access.log&lt;br /&gt;
But that will only work on container base images, not running containers. To 'execute' a command on a running or existing container, the command you want is exec. (Also used to interactively start bash shell above)&lt;br /&gt;
&lt;br /&gt;
EDIT: Use with discretion. Active data in RAM may use power.&lt;br /&gt;
&lt;br /&gt;
===Mysql Backup / Restore===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# Backup&lt;br /&gt;
docker exec CONTAINER /usr/bin/mysqldump -u root --password=root DATABASE &amp;gt; backup.sql&lt;br /&gt;
&lt;br /&gt;
# Restore&lt;br /&gt;
cat backup.sql | docker exec -i CONTAINER /usr/bin/mysql -u root --password=root DATABASE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
ref: https://gist.github.com/spalladino/6d981f7b33f6e0afe6bb&lt;br /&gt;
May not need to do this, if you keep the DB (ibdata files) in a local directory/volume via docker-compose.yml&lt;br /&gt;
e.g.&lt;br /&gt;
 mydb:&lt;br /&gt;
    image: mysql:9999&lt;br /&gt;
    volumes:&lt;br /&gt;
       - ./db_files:/var/lib/mysql&lt;br /&gt;
    restart: always&lt;br /&gt;
&lt;br /&gt;
===Limit docker logs===&lt;br /&gt;
Docker will keep lots of logs if you don't manage it.&lt;br /&gt;
https://github.com/docker/compose/issues/1083&lt;br /&gt;
https://docs.docker.com/compose/compose-file/#logging&lt;br /&gt;
https://stackoverflow.com/questions/31829587/docker-container-logs-taking-all-my-disk-space&lt;br /&gt;
view (all) logs with &lt;br /&gt;
 docker-compose logs&lt;br /&gt;
To limit a service's logs in docker-compose do the following:&lt;br /&gt;
* find a containers/services entry&lt;br /&gt;
* append to the end (watch the white space &amp;amp; no tabs)&lt;br /&gt;
     logging:&lt;br /&gt;
       driver: &amp;quot;json-file&amp;quot;&lt;br /&gt;
       options:&lt;br /&gt;
         max-size: &amp;quot;200k&amp;quot;&lt;br /&gt;
         max-file: &amp;quot;10&amp;quot;&lt;br /&gt;
The rule with logs, is nothing - unless you need it. Then everything. Any unnecessary logging is taxing the CPU / HDD.&lt;br /&gt;
Which leads me to...&lt;br /&gt;
&lt;br /&gt;
===view details about container===&lt;br /&gt;
To view paths, configuration settings, etc...&lt;br /&gt;
See&lt;br /&gt;
 docker inspect &amp;lt;name or id&amp;gt;&lt;br /&gt;
It's easier to grep these. the search in less wasn't working for me to find .LogPath for example.&lt;br /&gt;
 docker inspect mycontainer | grep log&lt;br /&gt;
Will show where the log files are located.&lt;br /&gt;
&lt;br /&gt;
===Installing Docker-compose from pip or github binary not Debian===&lt;br /&gt;
Subject. See official docker documentation which states the URL of&lt;br /&gt;
github.com/docker/compose/releases or pip.&lt;br /&gt;
&lt;br /&gt;
Pip is probably better.&lt;br /&gt;
 apt-get install python3-pip &lt;br /&gt;
 pip3 install docker-compose&lt;br /&gt;
&lt;br /&gt;
==Troubleshooting==&lt;br /&gt;
===Cannot start container: [0] Id already in use #20570===&lt;br /&gt;
* https://github.com/moby/moby/issues/20570&lt;br /&gt;
After update, unable to start container. Solution was found to be:&lt;br /&gt;
 docker-compose down -v then docker-compose up -d&lt;br /&gt;
Container was viewable with&lt;br /&gt;
 docker ps -a (not just docker ps)&lt;br /&gt;
==Fails==&lt;br /&gt;
===Creating a docker-compose with a stable or latest tag===&lt;br /&gt;
If you make a docker-compose file, you must link it to a marked version. You can later edit it, to use stable or latest, but one of the strengths of Docker is version control. If you create a docker-compose, always test on a specific version, should you need to roll back in the future. Otherwise, your scripts will fail in 2-20-200 years when the conf files are not supported anymore.&lt;br /&gt;
&lt;br /&gt;
e.g. https://github.com/nucreativa/frontaccounting-docker   (6th commit)&lt;br /&gt;
Here, the nginx config is no longer supported in vhosts, it must be in server_blocks. This would've been avoided by denoting a fixed nginx release instead of tag:latest.&lt;br /&gt;
&lt;br /&gt;
==See Also==&lt;br /&gt;
&lt;br /&gt;
* [[samba_docker_by_dlandon]]&lt;br /&gt;
&lt;br /&gt;
==External Links==&lt;br /&gt;
* https://github.com/LeCoupa/awesome-cheatsheets/blob/master/tools/docker.sh Information dense cheatsheet (unfortunately github)&lt;br /&gt;
* https://gist.github.com/spalladino/6d981f7b33f6e0afe6bb A million idiots type &amp;quot;thanks&amp;quot;. Also the source for the mysql backup command.&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
{{GNU\Linux}}&lt;/div&gt;</summary>
		<author><name>Adminguy</name></author>
	</entry>
	<entry>
		<id>http://steakwiki.com/index.php?title=Docker&amp;diff=975</id>
		<title>Docker</title>
		<link rel="alternate" type="text/html" href="http://steakwiki.com/index.php?title=Docker&amp;diff=975"/>
		<updated>2021-02-24T07:12:37Z</updated>

		<summary type="html">&lt;p&gt;Adminguy: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;small&amp;gt;Docker is a type of virtualization for Gnu\Linux that allows programs to run and share similar resources, without having a full OS for each image, but while still isolating each 'vm'.&lt;br /&gt;
&lt;br /&gt;
==General Tips==&lt;br /&gt;
It helps to read a book, and then keep it as a Reference. Here Using Docker By Adrian Mouat is a decent book. In fact, you should be reading books on any subject that interests you. Physical paper books, too.&lt;br /&gt;
&lt;br /&gt;
Docker is x86_64. ARM has a separate build. There is no i386.&lt;br /&gt;
&lt;br /&gt;
You will want 'some' RAM. I had 1GB on a P4 machine, and that was not enough. 4GB was enough. &lt;br /&gt;
&lt;br /&gt;
You should always use docker compose. Docker is possible to run on the command line, but with a compose file, you can write everything down in a much simpler fashion. Use compose. It's a separate install, currently. Install it. ''Seriously, just ignore the docker command lines. I consider them useless. More of a red herring for rookies.''&lt;br /&gt;
&lt;br /&gt;
===ARM is SOL===&lt;br /&gt;
I tried to use Docker on ARM, and while you might be able to install docker, you will find that images for your applications may not be there. e.g. you will find Nginx, but you won't find Gitlab. This means that docker is pretty much x86-64 only.&lt;br /&gt;
&lt;br /&gt;
==Docker Commands==&lt;br /&gt;
Here are commands you need to know. Just the necessary ones.&lt;br /&gt;
{{cmd| docker-compose up -d}} &lt;br /&gt;
 &lt;br /&gt;
Starts the containers in the docker compose file, if they aren't already started. the -d detaches from the stdout logging. You don't need to use stdout logging, you can use docker logs, but its there if you want it.&lt;br /&gt;
 {{cmd| docker ps }}&lt;br /&gt;
Lists containers running. If one fails to start, you'll see it missing from here&lt;br /&gt;
 {{cmd|docker logs &amp;lt;containername&amp;gt; }}&lt;br /&gt;
Gives you some logging output from the container. Often enough to troubleshoot. (also see tips below).&lt;br /&gt;
 {{cmd|docker exec -it &amp;lt;containername&amp;gt; /bin/bash}}&lt;br /&gt;
This will get you in a shell in the docker container. From here you can do what you need to. Most are debian, and need apt-get install less nano or whatever program you are missing. Ping is missing from possibly all containers, so if you want to test via ping, you'll have to apt-get it.&lt;br /&gt;
 {{cmd|docker-compose restart }}&lt;br /&gt;
This will restart all containers. However, I don't recommend it. Initting containers can get corrupted this way, and also its much easier to restart a single faulty container via...&lt;br /&gt;
 {{cmd|docker restart &amp;lt;containername&amp;gt; }}&lt;br /&gt;
This will restart one single container.&lt;br /&gt;
 {{cmd|docker cp &amp;lt;containername&amp;gt;:/dir/to/file dest }}&lt;br /&gt;
You can copy files from local machine to docker, or vice versa with this. Extremely useful.&lt;br /&gt;
&lt;br /&gt;
===Deleting Containers===&lt;br /&gt;
Less often, you might want to know &lt;br /&gt;
{{cmd|&lt;br /&gt;
 #!/bin/bash&lt;br /&gt;
 docker rm $(docker ps -a -q)&lt;br /&gt;
 docker rmi $(docker images -q) --force}}&lt;br /&gt;
&lt;br /&gt;
This starts over from scratch. This is how easy it is to reboot a docker from square one.  note: below command (rmi), only needed if you want to remove base images. Needed when updating a stable. Not needed when changing other parameters not related to base image. Also, this deletes all containers, which maybe you don't want to do, if you either A) only want to delete certain images you are testing B) have some containers with custom changes saved, and not backed up elsewhere.&lt;br /&gt;
&lt;br /&gt;
===Updating===&lt;br /&gt;
 docker images&lt;br /&gt;
 (shows out of date image)&lt;br /&gt;
 docker pull mysql&lt;br /&gt;
 (downloads new image)&lt;br /&gt;
 docker images&lt;br /&gt;
 (shows two versions of mysql. old and new)&lt;br /&gt;
 docker stop some_container_name&lt;br /&gt;
 docker rmi -f cjklfs23404&lt;br /&gt;
 (where cjklfs23404 is the old container alias under docker images)&lt;br /&gt;
 docker-compose up -d mysql&lt;br /&gt;
&lt;br /&gt;
====Containers don't all Restart?!====&lt;br /&gt;
Make sure to have in your docker compose for each container a '''restart:always'''&lt;br /&gt;
Otherwise, a container won't necessarily start when docker is restarted.&lt;br /&gt;
&lt;br /&gt;
===Search for images===&lt;br /&gt;
 docker search &amp;lt;imagename&amp;gt;&lt;br /&gt;
====Search for Versions of an image====&lt;br /&gt;
What if you want to see what versions are available for a given image? Say you want php, but don't know which to get. hub.docker.com is broken. Requires js, slow, and bad. You can't get a list of images on it easily. &lt;br /&gt;
&lt;br /&gt;
Solution:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
#https://stackoverflow.com/questions/28320134/how-can-i-list-all-tags-for-a-docker-image-on-a-remote-registry&lt;br /&gt;
#$1 means&lt;br /&gt;
#first parameter you pass to this script will be searched&lt;br /&gt;
#e.g. working: debian&lt;br /&gt;
#note: some have multiple layers&lt;br /&gt;
#e.g. gitea/gitea is literally entered as $1 == gitea/gitea  (teste, working)&lt;br /&gt;
# while debian is just debian. so be aware.&lt;br /&gt;
&lt;br /&gt;
wget -q https://registry.hub.docker.com/v1/repositories/$1/tags -O -  \&lt;br /&gt;
| sed -e 's/[][]//g' -e 's/&amp;quot;//g' -e 's/ //g' | tr '}' '\n'  | awk -F: '{print $3}'&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Ref: https://stackoverflow.com/questions/54418542/dockerhub-listing-all-available-versions-of-a-given-image&lt;br /&gt;
&lt;br /&gt;
https://stackoverflow.com/questions/28320134/how-can-i-list-all-tags-for-a-docker-image-on-a-remote-registry&lt;br /&gt;
&lt;br /&gt;
===Save Changes to Docker Image===&lt;br /&gt;
 docker commit&lt;br /&gt;
See official documentation.&lt;br /&gt;
&lt;br /&gt;
==Dockerfile==&lt;br /&gt;
Dockerfiles and compose are slightly confusing. Sometimes you see images run an entrypoint script, sometimes not. In any case, Dockerfiles are fundamental to reproducible builds.&lt;br /&gt;
&lt;br /&gt;
==Volumes==&lt;br /&gt;
Volumes can be handled at least two ways. The simplest is to store files in a local directory which is then mapped to the remote drive.&lt;br /&gt;
&lt;br /&gt;
e.g. docker-compose:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  nginx:&lt;br /&gt;
    image: nginx:####&lt;br /&gt;
    container_name: mynginxserver&lt;br /&gt;
    volumes:&lt;br /&gt;
      - ./nginx.conf:/etc/nginx/nginx.conf&lt;br /&gt;
      - /etc/letsencrypt/:/etc/letsencrypt/&lt;br /&gt;
      - ./local_dir/:/var/www/html/&lt;br /&gt;
      - ./local_logs/:/var/log/nginx/&lt;br /&gt;
    ports:&lt;br /&gt;
      - 80:80&lt;br /&gt;
      - 443:443&lt;br /&gt;
    restart: always&lt;br /&gt;
    logging:&lt;br /&gt;
      driver: &amp;quot;json-file&amp;quot;&lt;br /&gt;
      options:&lt;br /&gt;
        max-size: &amp;quot;200k&amp;quot;&lt;br /&gt;
        max-file: &amp;quot;10&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Here, in the local dir where docker-compose is run, the ./local_dir/ or ./local_logs will store the containers html or logs respectively. Simple. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
However, if you just have a volume, without a local directory, then it will save in /var/ somewhere (unintuitive... bad).&lt;br /&gt;
e.g. from Dolibarr:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
The Dolibarr installation and all data beyond what lives in the database&lt;br /&gt;
 (file uploads, etc) are stored in the unnamed docker volume volume&lt;br /&gt;
/var/www/html and /var/www/documents. The docker daemon will store&lt;br /&gt;
 that data within the docker directory /var/lib/docker/volumes/....&lt;br /&gt;
That means your data is saved even if the container crashes, is stopped&lt;br /&gt;
or deleted.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Specific Tips==&lt;br /&gt;
===YAML is space sensitive===&lt;br /&gt;
When you edit the .yml file for docker-compose, you have to hit spaces in a certain pattern (tabs not allowed). This is absurd, but just be aware. The errors are cryptic, and its often just because the spacing doesn't stick to what it expects.&lt;br /&gt;
===If you restart a containers namesake process, it will probably restart / reset the container===&lt;br /&gt;
So if you are troubleshooting an apache container, you edit some files, then /etc/init.d/apache2 restart, uh oh... You just undid all the edits you made, if they aren't in a permanent volume. You can shell in, make edits, and then exit the shell, but a service restart often resets the container.&lt;br /&gt;
===Consider a single reverse proxy, to handle multiple websites===&lt;br /&gt;
There are many ways to do this. I use an nginx proxy from scratch. You can also use some containers that are built for this purpose (I personally think it's bloated but a lot of people use Jason Wilder's proxy)&lt;br /&gt;
https://web.archive.org/web/https://github.com/jwilder/nginx-proxy - A lot of people swear by this, but I think it's straying too far to the high level.&lt;br /&gt;
===If you use a single reverse proxy, Lets Encrypt can be done easy===&lt;br /&gt;
In this case scenario you would have certbot on the host and a local volume that the proxy has access to which is the webroot of the Lets Encrypt scripts. The nginx proxy entry look something like this:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
location ^~ /.well-known {&lt;br /&gt;
     alias /var/www/html/.well-known/;&lt;br /&gt;
      autoindex on;&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
And this is put in every server declaration of nginx.conf. Real simple, real easy. The docker compose of the nginx proxy is something like:&lt;br /&gt;
&lt;br /&gt;
{{cat|docker-compose.yml|&lt;br /&gt;
nginx:&lt;br /&gt;
    image: nginx:latest&lt;br /&gt;
    container_name: custom_name_for_my_proxy&lt;br /&gt;
    volumes:&lt;br /&gt;
      - ./nginx.conf:/etc/nginx/nginx.conf&lt;br /&gt;
      - /etc/letsencrypt/:/etc/letsencrypt/&lt;br /&gt;
      - ./webroot/:/var/www/html/&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
The volumes section is extremely simple, don't be scared. There are two entries. Local and remote. You specify what folder will be the local directory which will be cloned to the host at the remote path you specify. So, the host runs certbot at /etc/letsencrypt, and this folder is cloned to the nginx proxy container, at the same location. Finally, webroot must be set in certbot, but it prompts you for this. And if you forget or get it wrong, it can be configured somewhere in /etc/letsencrypt. it's a one liner text entry).&lt;br /&gt;
&lt;br /&gt;
===Give every Container a Containername===&lt;br /&gt;
This makes it easier to refer to them later. All you need to do in the compose file is include container\_name: something. Much better than the gibberish they give these names if you don't include it.&lt;br /&gt;
===Beware of Interrupting Initting Containers===&lt;br /&gt;
When you first build a container, it might take 30-60 or more seconds to do whatever it needs to do. If, before then, you restart it... It may get corrupted. This has happened to me more than once. When you are testing a new container, and it doesn't seem to work for some inexplicable reason, create a container with a new name (it will create a new one), or delete the first one, and start it again.&lt;br /&gt;
===Put Apache or Program logs from the Container in a volume that is locally accessible===&lt;br /&gt;
This means you want a volume something like ./containerA\_files/logs:/var/www/log/apache2/ so that you can monitor the logs from your host machine easily. docker logs doesn't have everything.&lt;br /&gt;
===Only Restart Containers you need to Restart===&lt;br /&gt;
You can restart everything with docker-compose restart, but it's faster, and less prone to break initting containers, if you docker restart containername. Do the latter.&lt;br /&gt;
===Volumes Mounting Over Existing Directories===&lt;br /&gt;
As discussed here: https://web.archive.org/web/https://github.com/moby/moby/issues/4361, if you add a volume to an existing container, it will seem to delete the folder's contents. I've seen mixed behaviour with this. Sometimes it deletes it even if you start a new container with the folder... Other times it has not. In any case, just docker cp the files to the folder, then add the volume mount. This may not be the most graceful solution for upgrades, but it will work. Best practices would be here (See: dbxt commented Dec 14, 2014): https://web.archive.org/web/https://github.com/docker-library/wordpress/issues/10&lt;br /&gt;
===If you edit a docker-compose file you must restart the container with Docker-compose===&lt;br /&gt;
If you make a change in docker compose, you must docker stop service, then docker-compose up -d service. Otherwise the changes will not take effect. The mistake here, would be thinking that you could just docker stop service, then docker start service... That doesn't work.&lt;br /&gt;
===Keep verbose logging off your HDD with RAM only logging===&lt;br /&gt;
If you have e.g. apache/nginx write to your HDD with every website visit, it will quickly wear out your HDD (esp. SSD). Put verbose logging in the RAM only with a tmpfs mount. https://docs.docker.com/storage/tmpfs/&lt;br /&gt;
&lt;br /&gt;
e.g. (ref: https://stackoverflow.com/questions/41902930/docker-compose-tmpfs-not-working)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
services:&lt;br /&gt;
  ubuntu:&lt;br /&gt;
    image: ubuntu&lt;br /&gt;
    command: &amp;quot;bash -c 'mount'&amp;quot;&lt;br /&gt;
    volumes:&lt;br /&gt;
      - cache_vol:/var/cache&lt;br /&gt;
      - run_vol:/run&lt;br /&gt;
&lt;br /&gt;
volumes:&lt;br /&gt;
  run_vol:&lt;br /&gt;
    driver_opts:&lt;br /&gt;
      type: tmpfs&lt;br /&gt;
      device: tmpfs&lt;br /&gt;
  cache_vol:&lt;br /&gt;
    driver_opts:&lt;br /&gt;
      type: tmpfs&lt;br /&gt;
      device: tmpfs&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This also allows you to share the tmpfs mounts if needed.&lt;br /&gt;
&lt;br /&gt;
Access it from host via:&lt;br /&gt;
 docker exec -it nginx_server tail -F /run/shm/access.log&lt;br /&gt;
Note that you might think you can do&lt;br /&gt;
 docker container run my_nginx_server tail -F /run/shm/access.log&lt;br /&gt;
But that will only work on container base images, not running containers. To 'execute' a command on a running or existing container, the command you want is exec. (Also used to interactively start bash shell above)&lt;br /&gt;
&lt;br /&gt;
EDIT: Use with discretion. Active data in RAM may use power.&lt;br /&gt;
&lt;br /&gt;
===Mysql Backup / Restore===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# Backup&lt;br /&gt;
docker exec CONTAINER /usr/bin/mysqldump -u root --password=root DATABASE &amp;gt; backup.sql&lt;br /&gt;
&lt;br /&gt;
# Restore&lt;br /&gt;
cat backup.sql | docker exec -i CONTAINER /usr/bin/mysql -u root --password=root DATABASE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
ref: https://gist.github.com/spalladino/6d981f7b33f6e0afe6bb&lt;br /&gt;
May not need to do this, if you keep the DB (ibdata files) in a local directory/volume via docker-compose.yml&lt;br /&gt;
e.g.&lt;br /&gt;
 mydb:&lt;br /&gt;
    image: mysql:9999&lt;br /&gt;
    volumes:&lt;br /&gt;
       - ./db_files:/var/lib/mysql&lt;br /&gt;
    restart: always&lt;br /&gt;
&lt;br /&gt;
===Limit docker logs===&lt;br /&gt;
Docker will keep lots of logs if you don't manage it.&lt;br /&gt;
https://github.com/docker/compose/issues/1083&lt;br /&gt;
https://docs.docker.com/compose/compose-file/#logging&lt;br /&gt;
https://stackoverflow.com/questions/31829587/docker-container-logs-taking-all-my-disk-space&lt;br /&gt;
view (all) logs with &lt;br /&gt;
 docker-compose logs&lt;br /&gt;
To limit a service's logs in docker-compose do the following:&lt;br /&gt;
* find a containers/services entry&lt;br /&gt;
* append to the end (watch the white space &amp;amp; no tabs)&lt;br /&gt;
     logging:&lt;br /&gt;
       driver: &amp;quot;json-file&amp;quot;&lt;br /&gt;
       options:&lt;br /&gt;
         max-size: &amp;quot;200k&amp;quot;&lt;br /&gt;
         max-file: &amp;quot;10&amp;quot;&lt;br /&gt;
The rule with logs, is nothing - unless you need it. Then everything. Any unnecessary logging is taxing the CPU / HDD.&lt;br /&gt;
Which leads me to...&lt;br /&gt;
&lt;br /&gt;
===view details about container===&lt;br /&gt;
To view paths, configuration settings, etc...&lt;br /&gt;
See&lt;br /&gt;
 docker inspect &amp;lt;name or id&amp;gt;&lt;br /&gt;
It's easier to grep these. the search in less wasn't working for me to find .LogPath for example.&lt;br /&gt;
 docker inspect mycontainer | grep log&lt;br /&gt;
Will show where the log files are located.&lt;br /&gt;
&lt;br /&gt;
===Installing Docker-compose from pip or github binary not Debian===&lt;br /&gt;
Subject. See official docker documentation which states the URL of&lt;br /&gt;
github.com/docker/compose/releases or pip.&lt;br /&gt;
&lt;br /&gt;
Pip is probably better.&lt;br /&gt;
 apt-get install python3-pip &lt;br /&gt;
 pip3 install docker-compose&lt;br /&gt;
&lt;br /&gt;
==Troubleshooting==&lt;br /&gt;
===Cannot start container: [0] Id already in use #20570===&lt;br /&gt;
* https://github.com/moby/moby/issues/20570&lt;br /&gt;
After update, unable to start container. Solution was found to be:&lt;br /&gt;
 docker-compose down -v then docker-compose up -d&lt;br /&gt;
Container was viewable with&lt;br /&gt;
 docker ps -a (not just docker ps)&lt;br /&gt;
==Fails==&lt;br /&gt;
===Creating a docker-compose with a stable or latest tag===&lt;br /&gt;
If you make a docker-compose file, you must link it to a marked version. You can later edit it, to use stable or latest, but one of the strengths of Docker is version control. If you create a docker-compose, always test on a specific version, should you need to roll back in the future. Otherwise, your scripts will fail in 2-20-200 years when the conf files are not supported anymore.&lt;br /&gt;
&lt;br /&gt;
e.g. https://github.com/nucreativa/frontaccounting-docker   (6th commit)&lt;br /&gt;
Here, the nginx config is no longer supported in vhosts, it must be in server_blocks. This would've been avoided by denoting a fixed nginx release instead of tag:latest.&lt;br /&gt;
&lt;br /&gt;
==See Also==&lt;br /&gt;
&lt;br /&gt;
* [[samba_docker_by_dlandon]]&lt;br /&gt;
&lt;br /&gt;
==External Links==&lt;br /&gt;
* https://github.com/LeCoupa/awesome-cheatsheets/blob/master/tools/docker.sh Information dense cheatsheet (unfortunately github)&lt;br /&gt;
* https://gist.github.com/spalladino/6d981f7b33f6e0afe6bb A million idiots type &amp;quot;thanks&amp;quot;. Also the source for the mysql backup command.&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
{{GNU\Linux}}&lt;/div&gt;</summary>
		<author><name>Adminguy</name></author>
	</entry>
	<entry>
		<id>http://steakwiki.com/index.php?title=Alpine&amp;diff=974</id>
		<title>Alpine</title>
		<link rel="alternate" type="text/html" href="http://steakwiki.com/index.php?title=Alpine&amp;diff=974"/>
		<updated>2021-02-19T05:36:02Z</updated>

		<summary type="html">&lt;p&gt;Adminguy: /* Links */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;small&amp;gt;&lt;br /&gt;
==General Tips==&lt;br /&gt;
===Building a package in Alpine===&lt;br /&gt;
&lt;br /&gt;
https://wiki.alpinelinux.org/wiki/Category_talk:Developer_Documentation#Building_from_source_and_creating_packages&lt;br /&gt;
&lt;br /&gt;
https://wiki.alpinelinux.org/wiki/Custom_Kernel&lt;br /&gt;
&lt;br /&gt;
===Xorg video playback stutters upon suspend / resume===&lt;br /&gt;
&lt;br /&gt;
I added the following configuration to xorg.conf&lt;br /&gt;
 Section &amp;quot;Device&amp;quot;&lt;br /&gt;
   Identifier &amp;quot;Intel Graphics&amp;quot;&lt;br /&gt;
   Driver &amp;quot;intel&amp;quot;&lt;br /&gt;
   Option &amp;quot;AccelMethod&amp;quot; &amp;quot;uxa&amp;quot;&lt;br /&gt;
 EndSection&lt;br /&gt;
&lt;br /&gt;
This seems to resolve video playback issues. What happens is that the video will not play, though audio will. Only the first frame or so is visible. Video seems to be unable to display. This is a documented fix. The important part is AccelMethod.&lt;br /&gt;
https://wiki.archlinux.org/index.php/Intel_Graphics&lt;br /&gt;
Also documented in forums that I can't seem to find at the moment.&lt;br /&gt;
&lt;br /&gt;
===Python3 Script Won't Run===&lt;br /&gt;
 $ ztdl&lt;br /&gt;
 env: can't execute python&lt;br /&gt;
solution:&lt;br /&gt;
 python3 /usr/local/bin/ztdl&lt;br /&gt;
&lt;br /&gt;
===Cloning HDD===&lt;br /&gt;
&lt;br /&gt;
When cloning a hdd, do the&lt;br /&gt;
following:&lt;br /&gt;
*clonezilla or otherwise rsync partitions and recreate partitions to similar boundaries&lt;br /&gt;
by default clonezilla might fail, due to -C not being set. There is an icds option for restore, but it can either be edited into /usr/sbin/ocs-onthefly  for partclone or just rsync then:&lt;br /&gt;
*edit etc fstab  uuids&lt;br /&gt;
*edit (boot partition) grub/grub.cfg root=uuid=whatever to root=/dev/sda3&lt;br /&gt;
*can also be in /dev/sda1 - extlinux.conf&lt;br /&gt;
NOTE: normal editing of extlinux.conf can also be done with the extlinux in /etc/&lt;br /&gt;
&lt;br /&gt;
===Kernel, Initramfs recovery===&lt;br /&gt;
If upgrade fails halfway through for any reason (hdd failing, system in a broken state), you may be left with a unbootable machine. Keep an extra /boot/vmlinuz-lts and /boot/initramfs-lts and also a copy of that kernels /lib/modules/&amp;lt;kernelvers&amp;gt; around in case. I keep mine in a folder named /boot/recovery. Backup hdds help here. If you have a corrupt initramfs, or kernel, move the old files back over to /boot from another machine. Now, from the alpine machine (not from a different dist chroot, which didn't work for me btw), boot up, and run mkinitfs again. The command is easy to mess up, so here's the correct one (as of 3.12)&lt;br /&gt;
 mkinitfs -c /etc/mkinitfs/mkinitfs.conf -b / &amp;lt;kernelvers&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The kernel vers for the new kernel can be found from /lib/modules. It should also have a folder, as the script will load modules into the initramfs&lt;br /&gt;
ref:&lt;br /&gt;
https://wiki.alpinelinux.org/wiki/Running_Alpine_in_a_Docker_Container&lt;br /&gt;
&lt;br /&gt;
https://wiki.alpinelinux.org/wiki/NVME&lt;br /&gt;
&lt;br /&gt;
https://wiki.alpinelinux.org/wiki/Bootloaders&lt;br /&gt;
&lt;br /&gt;
https://wiki.alpinelinux.org/wiki/Setting_up_a_software_RAID_array&lt;br /&gt;
&lt;br /&gt;
===UTF-8 Characters===&lt;br /&gt;
If you see certain foreign language characters not showing up correctly, you can try installing different fonts.&lt;br /&gt;
 apk search ttf&lt;br /&gt;
But I found that changing in FF opensans to sans-serif fixed some of them for me. opensans had partial support for international characters.&lt;br /&gt;
&lt;br /&gt;
===History File Size===&lt;br /&gt;
Alpine uses ash, not bash. &lt;br /&gt;
 printenv&lt;br /&gt;
Histfilesize / histsize should be set correctly.&lt;br /&gt;
&lt;br /&gt;
===Search for package===&lt;br /&gt;
There's obv &lt;br /&gt;
 apk search &amp;lt;packagename&amp;gt; &lt;br /&gt;
but, there is also&lt;br /&gt;
 apk search -v --description 'something descriptive'&lt;br /&gt;
e.g.&lt;br /&gt;
 apk search -v --description 'browser'&lt;br /&gt;
&lt;br /&gt;
==Links==&lt;br /&gt;
https://wiki.alpinelinux.org/wiki/Configure_Wake-on-LAN Configure_Wake-on-LAN&lt;br /&gt;
&lt;br /&gt;
gcompat - way to run glibc programs&lt;br /&gt;
&lt;br /&gt;
https://wiki.alpinelinux.org/wiki/Running_glibc_programs&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{GNU\Linux}}&lt;/div&gt;</summary>
		<author><name>Adminguy</name></author>
	</entry>
	<entry>
		<id>http://steakwiki.com/index.php?title=Alpine&amp;diff=973</id>
		<title>Alpine</title>
		<link rel="alternate" type="text/html" href="http://steakwiki.com/index.php?title=Alpine&amp;diff=973"/>
		<updated>2021-02-19T05:35:50Z</updated>

		<summary type="html">&lt;p&gt;Adminguy: /* Links */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;small&amp;gt;&lt;br /&gt;
==General Tips==&lt;br /&gt;
===Building a package in Alpine===&lt;br /&gt;
&lt;br /&gt;
https://wiki.alpinelinux.org/wiki/Category_talk:Developer_Documentation#Building_from_source_and_creating_packages&lt;br /&gt;
&lt;br /&gt;
https://wiki.alpinelinux.org/wiki/Custom_Kernel&lt;br /&gt;
&lt;br /&gt;
===Xorg video playback stutters upon suspend / resume===&lt;br /&gt;
&lt;br /&gt;
I added the following configuration to xorg.conf&lt;br /&gt;
 Section &amp;quot;Device&amp;quot;&lt;br /&gt;
   Identifier &amp;quot;Intel Graphics&amp;quot;&lt;br /&gt;
   Driver &amp;quot;intel&amp;quot;&lt;br /&gt;
   Option &amp;quot;AccelMethod&amp;quot; &amp;quot;uxa&amp;quot;&lt;br /&gt;
 EndSection&lt;br /&gt;
&lt;br /&gt;
This seems to resolve video playback issues. What happens is that the video will not play, though audio will. Only the first frame or so is visible. Video seems to be unable to display. This is a documented fix. The important part is AccelMethod.&lt;br /&gt;
https://wiki.archlinux.org/index.php/Intel_Graphics&lt;br /&gt;
Also documented in forums that I can't seem to find at the moment.&lt;br /&gt;
&lt;br /&gt;
===Python3 Script Won't Run===&lt;br /&gt;
 $ ztdl&lt;br /&gt;
 env: can't execute python&lt;br /&gt;
solution:&lt;br /&gt;
 python3 /usr/local/bin/ztdl&lt;br /&gt;
&lt;br /&gt;
===Cloning HDD===&lt;br /&gt;
&lt;br /&gt;
When cloning a hdd, do the&lt;br /&gt;
following:&lt;br /&gt;
*clonezilla or otherwise rsync partitions and recreate partitions to similar boundaries&lt;br /&gt;
by default clonezilla might fail, due to -C not being set. There is an icds option for restore, but it can either be edited into /usr/sbin/ocs-onthefly  for partclone or just rsync then:&lt;br /&gt;
*edit etc fstab  uuids&lt;br /&gt;
*edit (boot partition) grub/grub.cfg root=uuid=whatever to root=/dev/sda3&lt;br /&gt;
*can also be in /dev/sda1 - extlinux.conf&lt;br /&gt;
NOTE: normal editing of extlinux.conf can also be done with the extlinux in /etc/&lt;br /&gt;
&lt;br /&gt;
===Kernel, Initramfs recovery===&lt;br /&gt;
If upgrade fails halfway through for any reason (hdd failing, system in a broken state), you may be left with a unbootable machine. Keep an extra /boot/vmlinuz-lts and /boot/initramfs-lts and also a copy of that kernels /lib/modules/&amp;lt;kernelvers&amp;gt; around in case. I keep mine in a folder named /boot/recovery. Backup hdds help here. If you have a corrupt initramfs, or kernel, move the old files back over to /boot from another machine. Now, from the alpine machine (not from a different dist chroot, which didn't work for me btw), boot up, and run mkinitfs again. The command is easy to mess up, so here's the correct one (as of 3.12)&lt;br /&gt;
 mkinitfs -c /etc/mkinitfs/mkinitfs.conf -b / &amp;lt;kernelvers&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The kernel vers for the new kernel can be found from /lib/modules. It should also have a folder, as the script will load modules into the initramfs&lt;br /&gt;
ref:&lt;br /&gt;
https://wiki.alpinelinux.org/wiki/Running_Alpine_in_a_Docker_Container&lt;br /&gt;
&lt;br /&gt;
https://wiki.alpinelinux.org/wiki/NVME&lt;br /&gt;
&lt;br /&gt;
https://wiki.alpinelinux.org/wiki/Bootloaders&lt;br /&gt;
&lt;br /&gt;
https://wiki.alpinelinux.org/wiki/Setting_up_a_software_RAID_array&lt;br /&gt;
&lt;br /&gt;
===UTF-8 Characters===&lt;br /&gt;
If you see certain foreign language characters not showing up correctly, you can try installing different fonts.&lt;br /&gt;
 apk search ttf&lt;br /&gt;
But I found that changing in FF opensans to sans-serif fixed some of them for me. opensans had partial support for international characters.&lt;br /&gt;
&lt;br /&gt;
===History File Size===&lt;br /&gt;
Alpine uses ash, not bash. &lt;br /&gt;
 printenv&lt;br /&gt;
Histfilesize / histsize should be set correctly.&lt;br /&gt;
&lt;br /&gt;
===Search for package===&lt;br /&gt;
There's obv &lt;br /&gt;
 apk search &amp;lt;packagename&amp;gt; &lt;br /&gt;
but, there is also&lt;br /&gt;
 apk search -v --description 'something descriptive'&lt;br /&gt;
e.g.&lt;br /&gt;
 apk search -v --description 'browser'&lt;br /&gt;
&lt;br /&gt;
==Links==&lt;br /&gt;
https://wiki.alpinelinux.org/wiki/Configure_Wake-on-LAN Configure_Wake-on-LAN&lt;br /&gt;
&lt;br /&gt;
gcompat - way to run glibc programs&lt;br /&gt;
&lt;br /&gt;
https://wiki.alpinelinux.org/wiki/Running_Glibc_Programs&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{GNU\Linux}}&lt;/div&gt;</summary>
		<author><name>Adminguy</name></author>
	</entry>
	<entry>
		<id>http://steakwiki.com/index.php?title=Parallax_Propeller_on_Linux_w/SimpleIDE&amp;diff=972</id>
		<title>Parallax Propeller on Linux w/SimpleIDE</title>
		<link rel="alternate" type="text/html" href="http://steakwiki.com/index.php?title=Parallax_Propeller_on_Linux_w/SimpleIDE&amp;diff=972"/>
		<updated>2021-02-19T05:29:10Z</updated>

		<summary type="html">&lt;p&gt;Adminguy: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;I recently got an issue of Nuts and Volts Electronics magazine to find the first article mentioning the Parallax Propeller 2. What is the Propeller, and why would I want it? The propeller is like a microcontroller/Arduino, and it is like an FPGA. It has 8 cores (P2) which can operate independently. In a perfect world, this means you have 8 microcontrollers on one chip.&lt;br /&gt;
&lt;br /&gt;
==Propeller and Linux Traps==&lt;br /&gt;
So, you come from the RPI world, or run FOSS, and want to use the P2 on Linux. Great. But, a warning: There are a lot of dead ends in Propeller world. The quick answer to get it working is do the following:&lt;br /&gt;
# Use Debian Buster (possibly stretch or jessie)&lt;br /&gt;
# Use the PropellerGCC website here: https://www.sites.google.com/site/propellergcc/ http://web.archive.org/web/20201009074325/https://sites.google.com/site/propellergcc/downloads/linux-downloads&lt;br /&gt;
# Download the .deb package. (backup: https://archive.org/details/simpleide-0.9.66-amd64-debian-linux)&lt;br /&gt;
# Install with gdebi (if you don't know what that is, look it up)&lt;br /&gt;
# Load simpleide, and expand the 2nd / 3rd panes by clicking the icon on the bottom left&lt;br /&gt;
# Choose generic board&lt;br /&gt;
# Connect to the board with an FTDI - USB adapter, or the propeller prop (I used a standard FTDI cable, and it worked)&lt;br /&gt;
# At least on the Mini, RX and TX are swapped. I shit you not. RX on the FTDI goes to RX on the Mini. Don't ask me why this was done.&lt;br /&gt;
# DTS on FTDI connects to RESET on mini. Mini is powered by 6.5-12V+. FTDI RX/TX is 3.3V.&lt;br /&gt;
# Should &amp;quot;just work&amp;quot;&lt;br /&gt;
&lt;br /&gt;
That's the tl;dr. Now for what did NOT work for me.&lt;br /&gt;
&lt;br /&gt;
===2020/12 - Recent SimpleIDE does not work easily===&lt;br /&gt;
SimpleIDE as of 2020 does not ship .deb packages. You must compile. Instant red flag. If you examine the install instructions for Linux, you will find that it refers to a non-existent .deb file. The documentation is outdated. Red flag no. 2. &lt;br /&gt;
&lt;br /&gt;
Even the official website tells you its supported, which is false. The install instructions in the git are out of date, and reference a non existent .deb. Ref: http://web.archive.org/web/20200805021922/http://learn.parallax.com/tutorials/language/propeller-c/propeller-c-set-simpleide/linux&lt;br /&gt;
http://web.archive.org/web/20200929084400/https://learn.parallax.com/tutorials/language/propeller-c/propeller-c-set-simpleide/raspberry-pi&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===PropWare - Dead Links fixed===&lt;br /&gt;
Go to the forums for most up to date instructions. There is a reasonable thread on Linux support here: https://forums.parallax.com/discussion/166656/simpleide-on-linux&lt;br /&gt;
Link: https://david.zemon.name/PropWare/#/about&lt;br /&gt;
Links were dead, but 'should' be fixed now.&lt;br /&gt;
&lt;br /&gt;
He has a github here: https://github.com/parallaxinc/PropWare which lacks current releases. So you are stuck using his website for recent releases.&lt;br /&gt;
&lt;br /&gt;
PropWare, currently replaces your packages (deb) cmake, which means if you use cmake, you may later get confused. There is a ticket, and I imagine it's a WIP. I tried compiling v2.1.0 for PropWare without luck.&lt;br /&gt;
&lt;br /&gt;
===2020/12 - Catalina: Source Build Required===&lt;br /&gt;
Catalina is another option, but for Linux you are shoehorned into source build only. That would be ok, if the dependencies were reasonable, but after trying all of the above for 2-3 hours, then getting here, I was not in the mood for another rabbit hole.&lt;br /&gt;
&lt;br /&gt;
The only difficult dependency of Catalina appears to be wxGTK, which is advised in the install instructions are requiring a build from source.&lt;br /&gt;
&lt;br /&gt;
===Conclusion===&lt;br /&gt;
Upon first glance, you will see that Propeller is OSHW, and fully released. You might assume that favor towards OSHW would extend to FOSS. Yes and no. Yes, it can work on Linux, but no the company is not necessarily as gung-ho about FOSS as it is OSHW. &lt;br /&gt;
&lt;br /&gt;
It's walking a tightrope walk to get the propeller to work on GNULinux machines. But, it does and can work. Just be aware that there are a lot of unmaintained dead ends, if you tread down this path.&lt;br /&gt;
&lt;br /&gt;
==Todo==&lt;br /&gt;
Get together the parallax data sheets and application notes and make a book.&lt;/div&gt;</summary>
		<author><name>Adminguy</name></author>
	</entry>
	<entry>
		<id>http://steakwiki.com/index.php?title=IT_Obfuscation&amp;diff=971</id>
		<title>IT Obfuscation</title>
		<link rel="alternate" type="text/html" href="http://steakwiki.com/index.php?title=IT_Obfuscation&amp;diff=971"/>
		<updated>2021-02-17T07:03:06Z</updated>

		<summary type="html">&lt;p&gt;Adminguy: /* Spam Filtering Services based on MX records */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;small&amp;gt;&lt;br /&gt;
===device cals vs user cals===&lt;br /&gt;
5 User Cals:&lt;br /&gt;
5 users (i.e. alice, bob, accounting, office, shipping)&lt;br /&gt;
These 5 users can connect from any computer in the office, but it must be those&lt;br /&gt;
users.&lt;br /&gt;
&lt;br /&gt;
5 Computer Cals: (they call this device cals, but computer cals is more intuitive. it's a&lt;br /&gt;
bit of obfuscation.)&lt;br /&gt;
There are 5 computers (Workstation1, WS2, WS3, WS4, WS5)&lt;br /&gt;
and any amount of user accounts can connect to the server, but they must be on one of these&lt;br /&gt;
five computers.&lt;br /&gt;
&lt;br /&gt;
The simple act of calling it device cals vs computer cals. Subtle changes make a big difference.&lt;br /&gt;
Is there even a difference between a device and a computer? Yes. Not all devices&lt;br /&gt;
are computers, but all computers are devices. Unless I can assign a CAL to&lt;br /&gt;
my toaster. That is an appliance aka a device. My power drill is a device. Heck, a device&lt;br /&gt;
can be nearly anything:&lt;br /&gt;
&lt;br /&gt;
device definition (https://dictionary.cambridge.org/dictionary/english/device): 1. an object&lt;br /&gt;
or machine that has been invented for a particular purpose: 2. a machine&lt;br /&gt;
&lt;br /&gt;
A hammer is an object invented with a particular purpose.&lt;br /&gt;
Therefore, I would like to assign a CAL to my hammer.&lt;br /&gt;
&lt;br /&gt;
Change the term device to computer, and it makes just a little bit more sense. But making sense&lt;br /&gt;
was not the goal. Sales was the goal. Obfuscation was the tool used&lt;br /&gt;
to achieve that goal. They don't want business owners to understand what&lt;br /&gt;
is going on. The key to being successful in ruthless business, is to have an uneducated&lt;br /&gt;
customer. The less informed your customers are, the more likely they are to make bad decisions.&lt;br /&gt;
this is important when you have a monopoly. because there may be better options, but the&lt;br /&gt;
company behind the monopoly doesn't want you to know that.&lt;br /&gt;
&lt;br /&gt;
And making bad decisions is what you are doing, when you use Windows in a corporate environment.  Thus ms is the driving force behind the covid lockdowns and the vaccinations. Because vax are an effective method of inserting potentially damaging foreign substances into the human body, especially when its gubermint sponsored. Folks end up brainwashed, and brainwashed folks don't make good decisions. the corps moves are quite transparent. Historically purchases have been to squander any potential threats to their hegemony. Hotmail (communication), Skype (communication), Nokia (aka AT&amp;amp;T, aka Bell Labs)... They bought github to monitor the foss folks. tracking of projects, and to see who needs to be targeted - who is a threat to their business model. what projects need to be stamped out. next they helped institute the lockdowns and promoted the vaccinations, because people are getting too smart, and vax are an effective method to control the population (to dumb them down).&lt;br /&gt;
&lt;br /&gt;
A funny aside, is that ideally they would like to shut github down (long term goal). But that simply isn't possible. The amount of people in software that would move to something else (many already have) is so great, that this inertia can't be stopped. Open/Free source software will win.*&lt;br /&gt;
&lt;br /&gt;
*Note: I can't make any guarantees for humans on planet earth winning/surviving though.&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Spam Filtering Services based on MX records ===&lt;br /&gt;
&lt;br /&gt;
There is a product which will do spam filtering on your email for you. You pay a subscription&lt;br /&gt;
and then point your mx records at the spam filter service. The spam filter service then&lt;br /&gt;
vets all incoming email, before forwarding the email to your servers. It's standard&lt;br /&gt;
stuff. &lt;br /&gt;
&lt;br /&gt;
So where's the bullshit?&lt;br /&gt;
&lt;br /&gt;
These solutions are geared towards MSP, aka IT companies (yes, MSP is a buzzword for IT&lt;br /&gt;
guy, and any IT guy/girl that refers to himself as an MSP, is full of it) which&lt;br /&gt;
means they obfuscate what they do. It's hard to find a straightforward example that&lt;br /&gt;
basically says:&lt;br /&gt;
 &amp;quot;you point mx at us, we (try to) remove spam, then we forward to your email server. &amp;quot; &lt;br /&gt;
That's basic caveman / layman explanation, and it's all you need. Instead, you get&lt;br /&gt;
bullshit. Loads. There will be a 'How it works&amp;quot; section that literally says&lt;br /&gt;
nothing, zero, about how it works. No mention of mx, no mention of mitm. Nothing.&lt;br /&gt;
There will be fluffy words like cloud, and antispam, antivirus, email gateway, targeted&lt;br /&gt;
threat protection. It's something the PR department thought up. Nowhere is&lt;br /&gt;
 &amp;quot;you point mx at us, we (try to) remove spam, then we forward to your email server. &amp;quot; &lt;br /&gt;
It's collusion, and I am not joking, because the great majority of these services&lt;br /&gt;
all advertise like this. It's a secret handshake, a wink-wink-nod-nod between the software&lt;br /&gt;
company and it guys. A mafia system. This isn't unique to IT industry &amp;lt;small&amp;gt;(for example some electronics chips will have data sheets that basically expect you to understand how to use the chip before reading the data sheet. The instructional information might sort of be in there, but it's so devoid of substance that it really wouldn't be able to teach anyone without external resources. It's more there just for the sake of something being there. Again, not limited to electronics data sheets. All kinds of trades play this game.)&amp;lt;/small&amp;gt;, but it deserves to&lt;br /&gt;
be pointed out.&lt;br /&gt;
&lt;br /&gt;
Some at least, try to explain.&lt;br /&gt;
https://mxmailfilter.com/&lt;br /&gt;
Although this one doesn't explicitly say it's an MX mitm, but it's more obvious.&lt;br /&gt;
Is it that the smaller players are trying to explain, while the big guys sit on their&lt;br /&gt;
laurels and obfuscate?&lt;br /&gt;
&lt;br /&gt;
I did find one that explained what they do, but I had to hunt, had to click down&lt;br /&gt;
through two levels from the homepage to get to it). Anyways, I'm not just&lt;br /&gt;
being silly here. The MX email filtering services really seem to all agree, that the&lt;br /&gt;
homepage will NOT tell you what it does in below terms. What a joke. Man I hate the&lt;br /&gt;
IT industry. And why shouldn't I? They are primarily proprietary software goons.&lt;br /&gt;
Like attracts like. And the proprietary software attracts proprietary software.&lt;br /&gt;
The IT industry however, is a topic for another article, and while I have more to &lt;br /&gt;
say about it, it won't be here.&lt;br /&gt;
ref: https://www.mxguarddog.com/faq.technical/&lt;br /&gt;
     &amp;lt;pre&amp;gt;In simple language, how does MX Guarddog work?&lt;br /&gt;
Our email security service (including anti-spam and anti-virus) use the MX records for your&lt;br /&gt;
domain to direct email to MX Guarddog's distributed network of servers. Our servers scan&lt;br /&gt;
incoming mail for email-borne threats and place bad mail into quarantine before reaching&lt;br /&gt;
your server.&lt;br /&gt;
&lt;br /&gt;
Messages that are clean are passed to your server where they are delivered to the inbox. &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
search term to find this product is&lt;br /&gt;
&lt;br /&gt;
 email filtering service mx&lt;br /&gt;
&amp;lt;small&amp;gt;*note that I don't recommend any of these services necessarily.&amp;lt;/small&amp;gt;&lt;br /&gt;
So there is at least product that explains it, but that's one out of 6, and only&lt;br /&gt;
if you know what you are looking for... The average &lt;br /&gt;
business owner is not going to find this. And that's the point. Uneducated users&lt;br /&gt;
are more valuable for crooked businesses. Uneducated users will accept the bullshit.&lt;br /&gt;
Proprietary software loves uneducated users. &lt;br /&gt;
&lt;br /&gt;
Power to the corporations.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;small&amp;gt;One might make the argument that: &amp;quot;These pages are geared towards IT guys because business owners are stupid and need their hands held OR don't allow for markup, and are too much effort to support.&amp;quot; That doesn't justify obfuscation. They could still explain what the product does. Whether they sell to end users or contractors is a separate matter. &lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;/div&gt;</summary>
		<author><name>Adminguy</name></author>
	</entry>
	<entry>
		<id>http://steakwiki.com/index.php?title=IT_Obfuscation&amp;diff=970</id>
		<title>IT Obfuscation</title>
		<link rel="alternate" type="text/html" href="http://steakwiki.com/index.php?title=IT_Obfuscation&amp;diff=970"/>
		<updated>2021-02-17T06:58:21Z</updated>

		<summary type="html">&lt;p&gt;Adminguy: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;small&amp;gt;&lt;br /&gt;
===device cals vs user cals===&lt;br /&gt;
5 User Cals:&lt;br /&gt;
5 users (i.e. alice, bob, accounting, office, shipping)&lt;br /&gt;
These 5 users can connect from any computer in the office, but it must be those&lt;br /&gt;
users.&lt;br /&gt;
&lt;br /&gt;
5 Computer Cals: (they call this device cals, but computer cals is more intuitive. it's a&lt;br /&gt;
bit of obfuscation.)&lt;br /&gt;
There are 5 computers (Workstation1, WS2, WS3, WS4, WS5)&lt;br /&gt;
and any amount of user accounts can connect to the server, but they must be on one of these&lt;br /&gt;
five computers.&lt;br /&gt;
&lt;br /&gt;
The simple act of calling it device cals vs computer cals. Subtle changes make a big difference.&lt;br /&gt;
Is there even a difference between a device and a computer? Yes. Not all devices&lt;br /&gt;
are computers, but all computers are devices. Unless I can assign a CAL to&lt;br /&gt;
my toaster. That is an appliance aka a device. My power drill is a device. Heck, a device&lt;br /&gt;
can be nearly anything:&lt;br /&gt;
&lt;br /&gt;
device definition (https://dictionary.cambridge.org/dictionary/english/device): 1. an object&lt;br /&gt;
or machine that has been invented for a particular purpose: 2. a machine&lt;br /&gt;
&lt;br /&gt;
A hammer is an object invented with a particular purpose.&lt;br /&gt;
Therefore, I would like to assign a CAL to my hammer.&lt;br /&gt;
&lt;br /&gt;
Change the term device to computer, and it makes just a little bit more sense. But making sense&lt;br /&gt;
was not the goal. Sales was the goal. Obfuscation was the tool used&lt;br /&gt;
to achieve that goal. They don't want business owners to understand what&lt;br /&gt;
is going on. The key to being successful in ruthless business, is to have an uneducated&lt;br /&gt;
customer. The less informed your customers are, the more likely they are to make bad decisions.&lt;br /&gt;
this is important when you have a monopoly. because there may be better options, but the&lt;br /&gt;
company behind the monopoly doesn't want you to know that.&lt;br /&gt;
&lt;br /&gt;
And making bad decisions is what you are doing, when you use Windows in a corporate environment.  Thus ms is the driving force behind the covid lockdowns and the vaccinations. Because vax are an effective method of inserting potentially damaging foreign substances into the human body, especially when its gubermint sponsored. Folks end up brainwashed, and brainwashed folks don't make good decisions. the corps moves are quite transparent. Historically purchases have been to squander any potential threats to their hegemony. Hotmail (communication), Skype (communication), Nokia (aka AT&amp;amp;T, aka Bell Labs)... They bought github to monitor the foss folks. tracking of projects, and to see who needs to be targeted - who is a threat to their business model. what projects need to be stamped out. next they helped institute the lockdowns and promoted the vaccinations, because people are getting too smart, and vax are an effective method to control the population (to dumb them down).&lt;br /&gt;
&lt;br /&gt;
A funny aside, is that ideally they would like to shut github down (long term goal). But that simply isn't possible. The amount of people in software that would move to something else (many already have) is so great, that this inertia can't be stopped. Open/Free source software will win.*&lt;br /&gt;
&lt;br /&gt;
*Note: I can't make any guarantees for humans on planet earth winning/surviving though.&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Spam Filtering Services based on MX records ===&lt;br /&gt;
&lt;br /&gt;
There is a product which will do spam filtering on your email for you. You pay a subscription&lt;br /&gt;
and then point your mx records at the spam filter service. The spam filter service then&lt;br /&gt;
vets all incoming email, before forwarding the email to your servers. It's standard&lt;br /&gt;
stuff. &lt;br /&gt;
&lt;br /&gt;
So where's the bullshit?&lt;br /&gt;
&lt;br /&gt;
These solutions are geared towards MSP, aka IT companies (yes, MSP is a buzzword for IT&lt;br /&gt;
guy, and any IT guy/girl that refers to himself as an MSP, is full of it) which&lt;br /&gt;
means they obfuscate what they do. It's hard to find a straightforward example that&lt;br /&gt;
basically says:&lt;br /&gt;
 &amp;quot;you point mx at us, we (try to) remove spam, then we forward to your email server. &amp;quot; &lt;br /&gt;
That's basic caveman / layman explanation, and it's all you need. Instead, you get&lt;br /&gt;
bullshit. Loads. There will be a 'How it works&amp;quot; section that literally says&lt;br /&gt;
nothing, zero, about how it works. No mention of mx, no mention of mitm. Nothing.&lt;br /&gt;
There will be fluffy words like cloud, and antispam, antivirus, email gateway, targeted&lt;br /&gt;
threat protection. It's something the PR department thought up. Nowhere is&lt;br /&gt;
 &amp;quot;you point mx at us, we (try to) remove spam, then we forward to your email server. &amp;quot; &lt;br /&gt;
It's collusion, and I am not joking, because the great majority of these services&lt;br /&gt;
all advertise like this. It's a secret handshake, a wink-wink-nod-nod between the software&lt;br /&gt;
company and it guys. A mafia system. This isn't unique to IT industry &amp;lt;small&amp;gt;(for example some electronics chips will have data sheets that basically expect you to understand how to use the chip before reading the data sheet. The instructional information might sort of be in there, but it's so devoid of substance that it really wouldn't be able to teach anyone without external resources. It's more there just for the sake of something being there. Again, not limited to electronics data sheets. All kinds of trades play this game.)&amp;lt;/small&amp;gt;, but it deserves to&lt;br /&gt;
be pointed out.&lt;br /&gt;
&lt;br /&gt;
Some at least, try to explain.&lt;br /&gt;
https://mxmailfilter.com/&lt;br /&gt;
Although this one doesn't explicitly say it's an MX mitm, but it's more obvious.&lt;br /&gt;
Is it that the smaller players are trying to explain, while the big guys sit on their&lt;br /&gt;
laurels and obfuscate?&lt;br /&gt;
&lt;br /&gt;
I did find one that explained what they do, but I had to hunt, had to click down&lt;br /&gt;
through two levels from the homepage to get to it). Anyways, I'm not just&lt;br /&gt;
being silly here. The MX email filtering services really seem to all agree, that the&lt;br /&gt;
homepage will NOT tell you what it does in below terms. What a joke. Man I hate the&lt;br /&gt;
IT industry. And why shouldn't I? They are primarily proprietary software goons.&lt;br /&gt;
Like attracts like. And the proprietary software attracts proprietary software.&lt;br /&gt;
The IT industry however, is a topic for another article, and while I have more to &lt;br /&gt;
say about it, it won't be here.&lt;br /&gt;
ref: https://www.mxguarddog.com/faq.technical/&lt;br /&gt;
     &amp;lt;pre&amp;gt;In simple language, how does MX Guarddog work?&lt;br /&gt;
Our email security service (including anti-spam and anti-virus) use the MX records for your&lt;br /&gt;
domain to direct email to MX Guarddog's distributed network of servers. Our servers scan&lt;br /&gt;
incoming mail for email-borne threats and place bad mail into quarantine before reaching&lt;br /&gt;
your server.&lt;br /&gt;
&lt;br /&gt;
Messages that are clean are passed to your server where they are delivered to the inbox. &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
search term to find this product is&lt;br /&gt;
&lt;br /&gt;
 email filtering service mx&lt;br /&gt;
&amp;lt;small&amp;gt;*note that I don't recommend any of these services necessarily.&amp;lt;/small&amp;gt;&lt;br /&gt;
So there is at least product that explains it, but that's one out of 6, and only&lt;br /&gt;
if you know what you are looking for... The average &lt;br /&gt;
business owner is not going to find this. And that's the point. Uneducated users&lt;br /&gt;
are more valuable for crooked businesses. Uneducated users will accept the bullshit.&lt;br /&gt;
Proprietary software loves uneducated users. &lt;br /&gt;
&lt;br /&gt;
Power to the corporations.&lt;/div&gt;</summary>
		<author><name>Adminguy</name></author>
	</entry>
	<entry>
		<id>http://steakwiki.com/index.php?title=Freecad&amp;diff=969</id>
		<title>Freecad</title>
		<link rel="alternate" type="text/html" href="http://steakwiki.com/index.php?title=Freecad&amp;diff=969"/>
		<updated>2021-02-10T04:35:10Z</updated>

		<summary type="html">&lt;p&gt;Adminguy: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Freecad is a mechanical design tool. It can be used in&lt;br /&gt;
* additive / subtraction mode&lt;br /&gt;
* sketching / constraint mode&lt;br /&gt;
&lt;br /&gt;
==0.18==&lt;br /&gt;
0.18 is the stable release for Devuan Beowulf.&lt;br /&gt;
===Adding Engraved Text to Shape===&lt;br /&gt;
This is tricky. It seems that it always is (to add engraved text).&lt;br /&gt;
&lt;br /&gt;
Make sure to extrude the text before adjusting x,y,z on the 3d plane. Otherwise the extrusion will be offset by the earlier placement.&lt;br /&gt;
&lt;br /&gt;
See freecad wiki tutorial (0.17). you can skip the sketcher part.&lt;br /&gt;
&lt;br /&gt;
For 0.18, some guides say to use shapestring to trimex. That didn't work for me. Trimex would fail.&lt;br /&gt;
&lt;br /&gt;
However, shapestring, to then PART workbench (not part design)(its bad design they are named&lt;br /&gt;
similarly is it not? Endlessly confusing.), To then part extrude worked. You must select a font for&lt;br /&gt;
the text. By default, it won't choose one for you. Not all work.&lt;br /&gt;
&lt;br /&gt;
Ugh. 30 minutes of my life&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
difference between trimex and part extrude is explained here:&lt;br /&gt;
https://wiki.freecadweb.org/Manual:Traditional_2D_drafting&lt;br /&gt;
&lt;br /&gt;
===Spreadsheets of values===&lt;br /&gt;
These are useful, but then if you duplicate a part, it makes a new spreadsheet.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===External Geometry===&lt;br /&gt;
When adding external geometry (0.18) you must have a near brandy new sketch.&lt;br /&gt;
click external geometry, select outside sketch, then draw the rectangle.&lt;br /&gt;
if you already have a rectangle, it will work. if you already have the rectangle,&lt;br /&gt;
then add a constraint, then delete that constraint... well it didnt work for me that time.&lt;br /&gt;
shift - select for Openinventor mouse.&lt;br /&gt;
&lt;br /&gt;
basic example sketch to get used to external geometry tool:&lt;br /&gt;
# start new body, then new sketch&lt;br /&gt;
# make square, horizontal cons. 20mm, vertical 20mm&lt;br /&gt;
# make new sketch (must be a new sketch, make sure it doesn't add this circle to the old sketch)&lt;br /&gt;
in new sketch (but still in same body, can't be new body)&lt;br /&gt;
# make circle. &lt;br /&gt;
# give it radius const. 4mm&lt;br /&gt;
# external geometry on top and side lines of rectange. when selected they should turn magenta&lt;br /&gt;
# Now, select two CORNER points, and then click horizontal constraint.&lt;br /&gt;
do not select the line (that will give you a blue line/constraint. not what we want)&lt;br /&gt;
done this way, it should work as expected.&lt;br /&gt;
&lt;br /&gt;
EDIT: just did this again today, and for the last step (click horizontal constraint) instead I chose the constrain distance tool (diagonal arrows) (see top menu bar - sketcher - sketcher constraints menu) and chose between two lines. One line of the external rectangle, one of the new rectangle.&lt;br /&gt;
&lt;br /&gt;
===Sketches freezing up.===&lt;br /&gt;
when adding a constraint, if you get it wrong, you get to a point where you can't delete a constraint&lt;br /&gt;
just close the sketch (not file just sketch) then reopen and delete.&lt;br /&gt;
&lt;br /&gt;
===Symmetry constraint===&lt;br /&gt;
Note: if you want to define a symmetry constraint with respect to a point, the order of the selection is important, depending on if you select the tool at the beginning or at the end.&lt;br /&gt;
&lt;br /&gt;
    If you click the tool first: select the first point, then the symmetry reference point, and finally the second point.&lt;br /&gt;
    If you click the tool last: select the first point, then the second point, and finally the symmetry reference point&lt;br /&gt;
Note: above taken verbatim from freecad wiki.&lt;br /&gt;
&lt;br /&gt;
So to get center constraint, do the former, and choose opposite points.&lt;br /&gt;
&lt;br /&gt;
===Offset item from center lines===&lt;br /&gt;
Offset square from center point. instead of symmetrical contraint, or vertical&lt;br /&gt;
or horizontal, choose the diagnoal line one. then enter an offset, based on a point, and the &lt;br /&gt;
middle lines. you may have to drag and drop it, to get it on one side or the other.&lt;br /&gt;
&lt;br /&gt;
===Addon Manager Fix for 0.18===&lt;br /&gt;
The bad news is that Addon Manager is broken on 0.18. Backwards compatibility is very important. This is one thing that made windows successful. Bad show on the freecad devs part. In their defense, it's a new feature, so this is somewhat acceptable. Good news, is that two small changes in 0.18 (debian 10) will fix it. It's python, so no re-compiling needed.&lt;br /&gt;
&lt;br /&gt;
Two fixes. One for macros, one for Workbenches.&lt;br /&gt;
&lt;br /&gt;
https://github.com/FreeCAD/FreeCAD/commit/258f9f1577e71e30f8696b266458df23042eefa5&lt;br /&gt;
&lt;br /&gt;
https://forum.freecadweb.org/viewtopic.php?f=3&amp;amp;t=51160&lt;br /&gt;
&lt;br /&gt;
tested in devuan beowulf.&lt;br /&gt;
&lt;br /&gt;
===Different Preferences Menus Show Depending on Which Workbench You Are In===&lt;br /&gt;
Subject. Edit -&amp;gt; preferences.&lt;br /&gt;
&lt;br /&gt;
===External Links===&lt;br /&gt;
* https://forum.freecadweb.org/viewtopic.php?f=3&amp;amp;t=38274&amp;amp;p=324418#p324418 - construction items (blue) and building items (white)&lt;br /&gt;
&lt;br /&gt;
{{GNU\Linux}}&lt;/div&gt;</summary>
		<author><name>Adminguy</name></author>
	</entry>
	<entry>
		<id>http://steakwiki.com/index.php?title=Assortment_Kits&amp;diff=968</id>
		<title>Assortment Kits</title>
		<link rel="alternate" type="text/html" href="http://steakwiki.com/index.php?title=Assortment_Kits&amp;diff=968"/>
		<updated>2021-02-10T04:08:18Z</updated>

		<summary type="html">&lt;p&gt;Adminguy: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Search auction sites for 'assortment kits' and you will find plastic boxes full of a variety of hardware and other equipment.&lt;br /&gt;
&lt;br /&gt;
List of useful assortment kits from local or chinese manufacturers&lt;br /&gt;
 * stand offs (m3 seems like a good start. m2 is likely a bit small)&lt;br /&gt;
 * crimp connectors &lt;br /&gt;
 * automotive connectors &lt;br /&gt;
 * wire nuts  (a kit is the only way to go with these. you never know what size you will need)&lt;br /&gt;
 * nuts and bolts (cheap but good for quick stuff)&lt;br /&gt;
 * washers (i like the huge washers, they are called fender washers) (these are not cheap), also lock washers (not spring washers which even nasa does not like according to https://en.wikipedia.org/wiki/Washer_(hardware))&lt;br /&gt;
 * Heat shrink tubing (clear is great, but 3:1 type, not 2:1, is the high end type).&lt;br /&gt;
 * 1000Pcs Micro Screws Nut Electronics Assortment Kit for Glasses Watch Cellphones&lt;br /&gt;
 * Threaded Inserts&lt;br /&gt;
 &lt;br /&gt;
Just search for &amp;quot;assortment kit&amp;quot;. don't ever buy the kits that are in the shape of a circle. those won't stack well in the cabinet.&lt;br /&gt;
&lt;br /&gt;
Keep in mind, some items may be of poor quality. The idea is that these are cheap and ready for quick work. Not to be used in production items.&lt;br /&gt;
&lt;br /&gt;
Harbor Freight stocks a few of these assortment kits. They may be scattered across the store.&lt;br /&gt;
&lt;br /&gt;
== Assortment Kit Wishlist ==&lt;br /&gt;
Hm...&lt;/div&gt;</summary>
		<author><name>Adminguy</name></author>
	</entry>
	<entry>
		<id>http://steakwiki.com/index.php?title=Assortment_Kits&amp;diff=967</id>
		<title>Assortment Kits</title>
		<link rel="alternate" type="text/html" href="http://steakwiki.com/index.php?title=Assortment_Kits&amp;diff=967"/>
		<updated>2021-02-10T04:07:09Z</updated>

		<summary type="html">&lt;p&gt;Adminguy: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Search auction sites for 'assortment kits' and you will find plastic boxes full of a variety of hardware and other equipment.&lt;br /&gt;
&lt;br /&gt;
List of useful assortment kits from local or chinese manufacturers&lt;br /&gt;
 * stand offs (m3 seems like a good start. m2 is likely a bit small)&lt;br /&gt;
 * crimp connectors &lt;br /&gt;
 * automotive connectors &lt;br /&gt;
 * wire nuts  (a kit is the only way to go with these. you never know what size you will need)&lt;br /&gt;
 * nuts and bolts (cheap but good for quick stuff)&lt;br /&gt;
 * washers (i like the huge washers, they are called fender washers) (these are not cheap), also lock washers (not spring washers which even nasa does not like according to https://en.wikipedia.org/wiki/Washer_(hardware))&lt;br /&gt;
 * Heat shrink tubing (clear is great, but 3:1 type, not 2:1, is the high end type).&lt;br /&gt;
 * 1000Pcs Micro Screws Nut Electronics Assortment Kit for Glasses Watch Cellphones&lt;br /&gt;
 * Threaded Insert&lt;br /&gt;
 &lt;br /&gt;
Just search for &amp;quot;assortment kit&amp;quot;. don't ever buy the kits that are in the shape of a circle. those won't stack well in the cabinet.&lt;br /&gt;
&lt;br /&gt;
Keep in mind, some items may be of poor quality. The idea is that these are cheap and ready for quick work. Not to be used in production items.&lt;br /&gt;
&lt;br /&gt;
Harbor Freight stocks a few of these assortment kits. They may be scattered across the store.&lt;br /&gt;
&lt;br /&gt;
== Assortment Kit Wishlist ==&lt;br /&gt;
Hm...&lt;/div&gt;</summary>
		<author><name>Adminguy</name></author>
	</entry>
	<entry>
		<id>http://steakwiki.com/index.php?title=Assortment_Kits&amp;diff=966</id>
		<title>Assortment Kits</title>
		<link rel="alternate" type="text/html" href="http://steakwiki.com/index.php?title=Assortment_Kits&amp;diff=966"/>
		<updated>2021-02-10T04:06:09Z</updated>

		<summary type="html">&lt;p&gt;Adminguy: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Search auction sites for 'assortment kits' and you will find plastic boxes full of a variety of hardware and other equipment.&lt;br /&gt;
&lt;br /&gt;
List of useful assortment kits from local or chinese manufacturers&lt;br /&gt;
 * stand offs (m3 seems like a good start. m2 is likely a bit small)&lt;br /&gt;
 * crimp connectors &lt;br /&gt;
 * automotive connectors &lt;br /&gt;
 * wire nuts  (a kit is the only way to go with these. you never know what size you will need)&lt;br /&gt;
 * nuts and bolts (cheap but good for quick stuff)&lt;br /&gt;
 * washers (i like the huge washers, they are called fender washers) (these are not cheap), also lock washers (not spring washers which even nasa does not like according to https://en.wikipedia.org/wiki/Washer_(hardware))&lt;br /&gt;
 * Heat shrink tubing (clear is great, but 3:1 type, not 2:1, is the high end type).&lt;br /&gt;
 * 1000Pcs Micro Screws Nut Electronics Assortment Kit for Glasses Watch Cellphones&lt;br /&gt;
 * Threaded Insert&lt;br /&gt;
 &lt;br /&gt;
Just search for &amp;quot;assortment kit&amp;quot;. don't ever buy the kits that are in the shape of a circle. those won't stack well in the cabinet.&lt;br /&gt;
&lt;br /&gt;
Keep in mind, some items may be of poor quality. The idea is that these are cheap and ready for quick work. Not to be used in production items.&lt;br /&gt;
&lt;br /&gt;
Harbor Freight stocks a few of these assortment kits. They may be scattered across the store.&lt;/div&gt;</summary>
		<author><name>Adminguy</name></author>
	</entry>
	<entry>
		<id>http://steakwiki.com/index.php?title=Assortment_Kits&amp;diff=965</id>
		<title>Assortment Kits</title>
		<link rel="alternate" type="text/html" href="http://steakwiki.com/index.php?title=Assortment_Kits&amp;diff=965"/>
		<updated>2021-02-10T04:05:51Z</updated>

		<summary type="html">&lt;p&gt;Adminguy: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Search auction sites for 'assortment kits' and you will find plastic boxes full of a variety of hardware and other equipment.&lt;br /&gt;
&lt;br /&gt;
List of useful assortment kits from local or chinese manufacturers&lt;br /&gt;
 * stand offs (m3 seems like a good start. m2 is likely a bit small)&lt;br /&gt;
 * crimp connectors &lt;br /&gt;
 * automotive connectors &lt;br /&gt;
 * wire nuts  (a kit is the only way to go with these. you never know what size you will need)&lt;br /&gt;
 * nuts and bolts (cheap but good for quick stuff)&lt;br /&gt;
 * washers (i like the huge washers, they are called fender washers) (these are not cheap), also lock washers (not spring washers which even nasa does not like according to https://en.wikipedia.org/wiki/Washer_(hardware))&lt;br /&gt;
 * Heat shrink tubing (clear is great, but 3:1 type, not 2:1, is the high end type).&lt;br /&gt;
 * 1000Pcs Micro Screws Nut Electronics Assortment Kit for Glasses Watch Cellphones&lt;br /&gt;
 * Threaded Insert assortment kit&lt;br /&gt;
 &lt;br /&gt;
Just search for &amp;quot;assortment kit&amp;quot;. don't ever buy the kits that are in the shape of a circle. those won't stack well in the cabinet.&lt;br /&gt;
&lt;br /&gt;
Keep in mind, some items may be of poor quality. The idea is that these are cheap and ready for quick work. Not to be used in production items.&lt;br /&gt;
&lt;br /&gt;
Harbor Freight stocks a few of these assortment kits. They may be scattered across the store.&lt;/div&gt;</summary>
		<author><name>Adminguy</name></author>
	</entry>
	<entry>
		<id>http://steakwiki.com/index.php?title=Freecad&amp;diff=964</id>
		<title>Freecad</title>
		<link rel="alternate" type="text/html" href="http://steakwiki.com/index.php?title=Freecad&amp;diff=964"/>
		<updated>2021-02-07T23:07:28Z</updated>

		<summary type="html">&lt;p&gt;Adminguy: /* Addon Manager Fix for 0.18 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Freecad is a mechanical design tool. It can be used in&lt;br /&gt;
* additive / subtraction mode&lt;br /&gt;
* sketching / constraint mode&lt;br /&gt;
&lt;br /&gt;
==0.18==&lt;br /&gt;
0.18 is the stable release for Devuan Beowulf.&lt;br /&gt;
===Adding Engraved Text to Shape===&lt;br /&gt;
This is tricky. It seems that it always is (to add engraved text).&lt;br /&gt;
&lt;br /&gt;
Make sure to extrude the text before adjusting x,y,z on the 3d plane. Otherwise the extrusion will be offset by the earlier placement.&lt;br /&gt;
&lt;br /&gt;
See freecad wiki tutorial (0.17). you can skip the sketcher part.&lt;br /&gt;
&lt;br /&gt;
For 0.18, some guides say to use shapestring to trimex. That didn't work for me. Trimex would fail.&lt;br /&gt;
&lt;br /&gt;
However, shapestring, to then PART workbench (not part design)(its bad design they are named&lt;br /&gt;
similarly is it not? Endlessly confusing.), To then part extrude worked. You must select a font for&lt;br /&gt;
the text. By default, it won't choose one for you. Not all work.&lt;br /&gt;
&lt;br /&gt;
Ugh. 30 minutes of my life&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
difference between trimex and part extrude is explained here:&lt;br /&gt;
https://wiki.freecadweb.org/Manual:Traditional_2D_drafting&lt;br /&gt;
&lt;br /&gt;
===Spreadsheets of values===&lt;br /&gt;
These are useful, but then if you duplicate a part, it makes a new spreadsheet.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===External Geometry===&lt;br /&gt;
When adding external geometry (0.18) you must have a near brandy new sketch.&lt;br /&gt;
click external geometry, select outside sketch, then draw the rectangle.&lt;br /&gt;
if you already have a rectangle, it will work. if you already have the rectangle,&lt;br /&gt;
then add a constraint, then delete that constraint... well it didnt work for me that time.&lt;br /&gt;
shift - select for Openinventor mouse.&lt;br /&gt;
&lt;br /&gt;
basic example sketch to get used to external geometry tool:&lt;br /&gt;
# start new body, then new sketch&lt;br /&gt;
# make square, horizontal cons. 20mm, vertical 20mm&lt;br /&gt;
# make new sketch (must be a new sketch, make sure it doesn't add this circle to the old sketch)&lt;br /&gt;
in new sketch (but still in same body, can't be new body)&lt;br /&gt;
# make circle. &lt;br /&gt;
# give it radius const. 4mm&lt;br /&gt;
# external geometry on top and side lines of rectange. when selected they should turn magenta&lt;br /&gt;
# Now, select two CORNER points, and then click horizontal constraint.&lt;br /&gt;
do not select the line (that will give you a blue line/constraint. not what we want)&lt;br /&gt;
done this way, it should work as expected.&lt;br /&gt;
&lt;br /&gt;
EDIT: just did this again today, and for the last step (click horizontal constraint) instead I chose the constrain distance tool (diagonal arrows) (see top menu bar - sketcher - sketcher constraints menu) and chose between two lines. One line of the external rectangle, one of the new rectangle.&lt;br /&gt;
&lt;br /&gt;
===Sketches freezing up.===&lt;br /&gt;
when adding a constraint, if you get it wrong, you get to a point where you can't delete a constraint&lt;br /&gt;
just close the sketch (not file just sketch) then reopen and delete.&lt;br /&gt;
&lt;br /&gt;
===Symmetry constraint===&lt;br /&gt;
Note: if you want to define a symmetry constraint with respect to a point, the order of the selection is important, depending on if you select the tool at the beginning or at the end.&lt;br /&gt;
&lt;br /&gt;
    If you click the tool first: select the first point, then the symmetry reference point, and finally the second point.&lt;br /&gt;
    If you click the tool last: select the first point, then the second point, and finally the symmetry reference point&lt;br /&gt;
Note: above taken verbatim from freecad wiki.&lt;br /&gt;
&lt;br /&gt;
So to get center constraint, do the former, and choose opposite points.&lt;br /&gt;
&lt;br /&gt;
===Offset item from center lines===&lt;br /&gt;
Offset square from center point. instead of symmetrical contraint, or vertical&lt;br /&gt;
or horizontal, choose the diagnoal line one. then enter an offset, based on a point, and the &lt;br /&gt;
middle lines. you may have to drag and drop it, to get it on one side or the other.&lt;br /&gt;
&lt;br /&gt;
===Addon Manager Fix for 0.18===&lt;br /&gt;
The bad news is that Addon Manager is broken on 0.18. Backwards compatibility is very important. This is one thing that made windows successful. Bad show on the freecad devs part. In their defense, it's a new feature, so this is somewhat acceptable. Good news, is that two small changes in 0.18 (debian 10) will fix it. It's python, so no re-compiling needed.&lt;br /&gt;
&lt;br /&gt;
Two fixes. One for macros, one for Workbenches.&lt;br /&gt;
&lt;br /&gt;
https://github.com/FreeCAD/FreeCAD/commit/258f9f1577e71e30f8696b266458df23042eefa5&lt;br /&gt;
&lt;br /&gt;
https://forum.freecadweb.org/viewtopic.php?f=3&amp;amp;t=51160&lt;br /&gt;
&lt;br /&gt;
tested in devuan beowulf.&lt;br /&gt;
&lt;br /&gt;
===Different Preferences Menus Show Depending on Which Workbench You Are In===&lt;br /&gt;
Subject. Edit -&amp;gt; preferences.&lt;br /&gt;
&lt;br /&gt;
{{GNU\Linux}}&lt;/div&gt;</summary>
		<author><name>Adminguy</name></author>
	</entry>
	<entry>
		<id>http://steakwiki.com/index.php?title=Freecad&amp;diff=963</id>
		<title>Freecad</title>
		<link rel="alternate" type="text/html" href="http://steakwiki.com/index.php?title=Freecad&amp;diff=963"/>
		<updated>2021-02-07T22:58:37Z</updated>

		<summary type="html">&lt;p&gt;Adminguy: /* Addon Manager Fix for 0.18 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Freecad is a mechanical design tool. It can be used in&lt;br /&gt;
* additive / subtraction mode&lt;br /&gt;
* sketching / constraint mode&lt;br /&gt;
&lt;br /&gt;
==0.18==&lt;br /&gt;
0.18 is the stable release for Devuan Beowulf.&lt;br /&gt;
===Adding Engraved Text to Shape===&lt;br /&gt;
This is tricky. It seems that it always is (to add engraved text).&lt;br /&gt;
&lt;br /&gt;
Make sure to extrude the text before adjusting x,y,z on the 3d plane. Otherwise the extrusion will be offset by the earlier placement.&lt;br /&gt;
&lt;br /&gt;
See freecad wiki tutorial (0.17). you can skip the sketcher part.&lt;br /&gt;
&lt;br /&gt;
For 0.18, some guides say to use shapestring to trimex. That didn't work for me. Trimex would fail.&lt;br /&gt;
&lt;br /&gt;
However, shapestring, to then PART workbench (not part design)(its bad design they are named&lt;br /&gt;
similarly is it not? Endlessly confusing.), To then part extrude worked. You must select a font for&lt;br /&gt;
the text. By default, it won't choose one for you. Not all work.&lt;br /&gt;
&lt;br /&gt;
Ugh. 30 minutes of my life&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
difference between trimex and part extrude is explained here:&lt;br /&gt;
https://wiki.freecadweb.org/Manual:Traditional_2D_drafting&lt;br /&gt;
&lt;br /&gt;
===Spreadsheets of values===&lt;br /&gt;
These are useful, but then if you duplicate a part, it makes a new spreadsheet.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===External Geometry===&lt;br /&gt;
When adding external geometry (0.18) you must have a near brandy new sketch.&lt;br /&gt;
click external geometry, select outside sketch, then draw the rectangle.&lt;br /&gt;
if you already have a rectangle, it will work. if you already have the rectangle,&lt;br /&gt;
then add a constraint, then delete that constraint... well it didnt work for me that time.&lt;br /&gt;
shift - select for Openinventor mouse.&lt;br /&gt;
&lt;br /&gt;
basic example sketch to get used to external geometry tool:&lt;br /&gt;
# start new body, then new sketch&lt;br /&gt;
# make square, horizontal cons. 20mm, vertical 20mm&lt;br /&gt;
# make new sketch (must be a new sketch, make sure it doesn't add this circle to the old sketch)&lt;br /&gt;
in new sketch (but still in same body, can't be new body)&lt;br /&gt;
# make circle. &lt;br /&gt;
# give it radius const. 4mm&lt;br /&gt;
# external geometry on top and side lines of rectange. when selected they should turn magenta&lt;br /&gt;
# Now, select two CORNER points, and then click horizontal constraint.&lt;br /&gt;
do not select the line (that will give you a blue line/constraint. not what we want)&lt;br /&gt;
done this way, it should work as expected.&lt;br /&gt;
&lt;br /&gt;
EDIT: just did this again today, and for the last step (click horizontal constraint) instead I chose the constrain distance tool (diagonal arrows) (see top menu bar - sketcher - sketcher constraints menu) and chose between two lines. One line of the external rectangle, one of the new rectangle.&lt;br /&gt;
&lt;br /&gt;
===Sketches freezing up.===&lt;br /&gt;
when adding a constraint, if you get it wrong, you get to a point where you can't delete a constraint&lt;br /&gt;
just close the sketch (not file just sketch) then reopen and delete.&lt;br /&gt;
&lt;br /&gt;
===Symmetry constraint===&lt;br /&gt;
Note: if you want to define a symmetry constraint with respect to a point, the order of the selection is important, depending on if you select the tool at the beginning or at the end.&lt;br /&gt;
&lt;br /&gt;
    If you click the tool first: select the first point, then the symmetry reference point, and finally the second point.&lt;br /&gt;
    If you click the tool last: select the first point, then the second point, and finally the symmetry reference point&lt;br /&gt;
Note: above taken verbatim from freecad wiki.&lt;br /&gt;
&lt;br /&gt;
So to get center constraint, do the former, and choose opposite points.&lt;br /&gt;
&lt;br /&gt;
===Offset item from center lines===&lt;br /&gt;
Offset square from center point. instead of symmetrical contraint, or vertical&lt;br /&gt;
or horizontal, choose the diagnoal line one. then enter an offset, based on a point, and the &lt;br /&gt;
middle lines. you may have to drag and drop it, to get it on one side or the other.&lt;br /&gt;
&lt;br /&gt;
===Addon Manager Fix for 0.18===&lt;br /&gt;
The bad news is that Addon Manager is broken on 0.18. Backwards compatibility is very important. This is one thing that made windows successful. Bad show on the freecad devs part. In their defense, it's a new feature, so this is somewhat acceptable. Good news, is that two small changes in 0.18 (debian 10) will fix it. It's python, so no re-compiling needed.&lt;br /&gt;
&lt;br /&gt;
Two fixes. One for macros, one for Workbenches.&lt;br /&gt;
&lt;br /&gt;
https://github.com/FreeCAD/FreeCAD/commit/258f9f1577e71e30f8696b266458df23042eefa5&lt;br /&gt;
&lt;br /&gt;
https://forum.freecadweb.org/viewtopic.php?f=3&amp;amp;t=51160&lt;br /&gt;
&lt;br /&gt;
tested in devuan beowulf.&lt;br /&gt;
&lt;br /&gt;
{{GNU\Linux}}&lt;/div&gt;</summary>
		<author><name>Adminguy</name></author>
	</entry>
	<entry>
		<id>http://steakwiki.com/index.php?title=Freecad&amp;diff=962</id>
		<title>Freecad</title>
		<link rel="alternate" type="text/html" href="http://steakwiki.com/index.php?title=Freecad&amp;diff=962"/>
		<updated>2021-02-07T22:57:46Z</updated>

		<summary type="html">&lt;p&gt;Adminguy: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Freecad is a mechanical design tool. It can be used in&lt;br /&gt;
* additive / subtraction mode&lt;br /&gt;
* sketching / constraint mode&lt;br /&gt;
&lt;br /&gt;
==0.18==&lt;br /&gt;
0.18 is the stable release for Devuan Beowulf.&lt;br /&gt;
===Adding Engraved Text to Shape===&lt;br /&gt;
This is tricky. It seems that it always is (to add engraved text).&lt;br /&gt;
&lt;br /&gt;
Make sure to extrude the text before adjusting x,y,z on the 3d plane. Otherwise the extrusion will be offset by the earlier placement.&lt;br /&gt;
&lt;br /&gt;
See freecad wiki tutorial (0.17). you can skip the sketcher part.&lt;br /&gt;
&lt;br /&gt;
For 0.18, some guides say to use shapestring to trimex. That didn't work for me. Trimex would fail.&lt;br /&gt;
&lt;br /&gt;
However, shapestring, to then PART workbench (not part design)(its bad design they are named&lt;br /&gt;
similarly is it not? Endlessly confusing.), To then part extrude worked. You must select a font for&lt;br /&gt;
the text. By default, it won't choose one for you. Not all work.&lt;br /&gt;
&lt;br /&gt;
Ugh. 30 minutes of my life&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
difference between trimex and part extrude is explained here:&lt;br /&gt;
https://wiki.freecadweb.org/Manual:Traditional_2D_drafting&lt;br /&gt;
&lt;br /&gt;
===Spreadsheets of values===&lt;br /&gt;
These are useful, but then if you duplicate a part, it makes a new spreadsheet.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===External Geometry===&lt;br /&gt;
When adding external geometry (0.18) you must have a near brandy new sketch.&lt;br /&gt;
click external geometry, select outside sketch, then draw the rectangle.&lt;br /&gt;
if you already have a rectangle, it will work. if you already have the rectangle,&lt;br /&gt;
then add a constraint, then delete that constraint... well it didnt work for me that time.&lt;br /&gt;
shift - select for Openinventor mouse.&lt;br /&gt;
&lt;br /&gt;
basic example sketch to get used to external geometry tool:&lt;br /&gt;
# start new body, then new sketch&lt;br /&gt;
# make square, horizontal cons. 20mm, vertical 20mm&lt;br /&gt;
# make new sketch (must be a new sketch, make sure it doesn't add this circle to the old sketch)&lt;br /&gt;
in new sketch (but still in same body, can't be new body)&lt;br /&gt;
# make circle. &lt;br /&gt;
# give it radius const. 4mm&lt;br /&gt;
# external geometry on top and side lines of rectange. when selected they should turn magenta&lt;br /&gt;
# Now, select two CORNER points, and then click horizontal constraint.&lt;br /&gt;
do not select the line (that will give you a blue line/constraint. not what we want)&lt;br /&gt;
done this way, it should work as expected.&lt;br /&gt;
&lt;br /&gt;
EDIT: just did this again today, and for the last step (click horizontal constraint) instead I chose the constrain distance tool (diagonal arrows) (see top menu bar - sketcher - sketcher constraints menu) and chose between two lines. One line of the external rectangle, one of the new rectangle.&lt;br /&gt;
&lt;br /&gt;
===Sketches freezing up.===&lt;br /&gt;
when adding a constraint, if you get it wrong, you get to a point where you can't delete a constraint&lt;br /&gt;
just close the sketch (not file just sketch) then reopen and delete.&lt;br /&gt;
&lt;br /&gt;
===Symmetry constraint===&lt;br /&gt;
Note: if you want to define a symmetry constraint with respect to a point, the order of the selection is important, depending on if you select the tool at the beginning or at the end.&lt;br /&gt;
&lt;br /&gt;
    If you click the tool first: select the first point, then the symmetry reference point, and finally the second point.&lt;br /&gt;
    If you click the tool last: select the first point, then the second point, and finally the symmetry reference point&lt;br /&gt;
Note: above taken verbatim from freecad wiki.&lt;br /&gt;
&lt;br /&gt;
So to get center constraint, do the former, and choose opposite points.&lt;br /&gt;
&lt;br /&gt;
===Offset item from center lines===&lt;br /&gt;
Offset square from center point. instead of symmetrical contraint, or vertical&lt;br /&gt;
or horizontal, choose the diagnoal line one. then enter an offset, based on a point, and the &lt;br /&gt;
middle lines. you may have to drag and drop it, to get it on one side or the other.&lt;br /&gt;
&lt;br /&gt;
===Addon Manager Fix for 0.18===&lt;br /&gt;
The bad news is that Addon Manager is broken on 0.18. Backwards compatibility is very important. This is one thing that made windows successful. Bad show on the freecad devs part. In their defense, it's a new feature, so this is somewhat acceptable. Good news, is that two small changes in 0.18 (debian 10) will fix it. It's python, so no re-compiling needed.&lt;br /&gt;
&lt;br /&gt;
Two fixes. One for macros, one for Workbenches.&lt;br /&gt;
&lt;br /&gt;
https://github.com/FreeCAD/FreeCAD/commit/258f9f1577e71e30f8696b266458df23042eefa5&lt;br /&gt;
https://forum.freecadweb.org/viewtopic.php?f=3&amp;amp;t=51160&lt;br /&gt;
&lt;br /&gt;
tested in devuan beowulf.&lt;br /&gt;
&lt;br /&gt;
{{GNU\Linux}}&lt;/div&gt;</summary>
		<author><name>Adminguy</name></author>
	</entry>
	<entry>
		<id>http://steakwiki.com/index.php?title=Regressions_Of_GNU%5CLinux&amp;diff=961</id>
		<title>Regressions Of GNU\Linux</title>
		<link rel="alternate" type="text/html" href="http://steakwiki.com/index.php?title=Regressions_Of_GNU%5CLinux&amp;diff=961"/>
		<updated>2021-02-05T21:09:27Z</updated>

		<summary type="html">&lt;p&gt;Adminguy: /* Raspberry Pi OS Sells Out Users to Proprietary Software via Telemetry */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Change is not always for the better. This page chronicles bull*$&amp;amp;! that has come down the Linux pipeline.&lt;br /&gt;
&lt;br /&gt;
http://web.archive.org/web/http://www.ariel.com.au/jokes/The\_Evolution\_of\_a\_Programmer.html&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Debian ==&lt;br /&gt;
&lt;br /&gt;
===Predictable Network Interface Names===&lt;br /&gt;
Someone has controversially decided that it is better for systems to have obtuse and confusing ethernet and wireless interface abbreviations such as enp0s25 instead of eth0. Remember this makes things simpler, and easier for people (but who?). &lt;br /&gt;
&lt;br /&gt;
In reality, most people get the shaft, and perhaps 10% (a small proportion) of users benefit. This raises the bar for entry level people to get started. Adding unnecessary complexity to Linux.&lt;br /&gt;
&lt;br /&gt;
=== Apt instead of Apt-get ===&lt;br /&gt;
This is a tentative, based on whether they remove support for apt-get. If that is the end goal, then this will be a valid regression,&lt;br /&gt;
until then, they live side by side. I don't need apt, when apt-get does the job.  Needless changes. There must be something more important to do than this.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Debian 10: iptables has been replaced with nftables, after nearly 20 years ===&lt;br /&gt;
&amp;quot;Those are some great firewall rules you've configured there. It would be a shame if someone was to make them obsolete.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
It started with Ipchains in 1998. In 2000, there was the last stable release of ipchains, which means if not by then, shortly after iptables took over. It's been 19, 19 years since then. Suddenly now, a new firewall is needed. Is this necessary for most people? That is the question.&lt;br /&gt;
&lt;br /&gt;
From Wikipedia https://en.m.wikipedia.org/wiki/Nftables&lt;br /&gt;
&lt;br /&gt;
A command to drop any packets with the destination IP address 1.2.3.4:&lt;br /&gt;
&lt;br /&gt;
iptables was: &lt;br /&gt;
 iptables -A OUTPUT -d 1.2.3.4 -j DROP&lt;br /&gt;
&lt;br /&gt;
nftables now is:&lt;br /&gt;
 nft add rule ip filter output ip daddr 1.2.3.4 drop&lt;br /&gt;
&lt;br /&gt;
More complex. Fail.&lt;br /&gt;
&amp;lt;small&amp;gt;EDIT: in hindsight, It's come to my attention that most common nft commands will have the format of &amp;quot;nft add rule&amp;quot; something something, so essentially, you are only memorizing everything after &amp;quot;nft add rule&amp;quot;. That makes it a bit better, but still a hurdle, that average folks will have to get over. An initial look at the long string of nft commands is bound to cause people to lock up, and not be able to process anything further. Smoke and mirrors. Regardless, the accurate comparison is then:&lt;br /&gt;
 &amp;quot;cmd&amp;quot; -A OUTPUT -d 1.2.3.4 -j DROP&lt;br /&gt;
and&lt;br /&gt;
 &amp;quot;cmd&amp;quot; ip filter output ip daddr 1.2.3.4 drop&lt;br /&gt;
It's apparent that the firewall has tried to become more self describing, which can be a good thing. Perhaps a more self describing nature will elucidate people on the actual workings of the firewall better. That would be the ideal. I haven't used it yet enough to say.&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
With one fell swoop, thousands of iptables scripts and programs that use iptables were broken. &lt;br /&gt;
&amp;lt;small&amp;gt;Note: technically iptables-legacy can be used. At least for now. Woe is the day support is removed for that.&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As an example, in 2020/10 This has bitten me with https://github.com/fail2ban/fail2ban/issues/2741&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    Fail2ban don't attempt to execute nft file. I tried to add full path to nft in config file. No luck...&lt;br /&gt;
&lt;br /&gt;
 Please be aware that due to ipv6 support (see #1742) fail2ban executes actionstart on demand (by first ban, family dependent). So by design you'd not see nft called unless first ban occurs.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Existing fail2ban functionality (when fail2ban started, new table f2b-sshd or f2b-whatever was created. Now apparently it's not created until the first account is added to the banlist.) has been changed. This leads the admin to think fail2ban isn't working when the table doesn't exist. This results in lost time.&lt;br /&gt;
&lt;br /&gt;
=== ifconfig replaced with ip ===&lt;br /&gt;
ifconfig, is simpler to use, and easier to view (more symmetrical than ip addr) for basic nic information, or setting an ip (ifconfig eth# 192.168.1.2 netmask 255.255.255.0). ip is unnecessary complexity for most use cases. This raises the bar for entry level people to get started. Adding unnecessary complexity to Linux.&lt;br /&gt;
&lt;br /&gt;
ifconfig remains in /sbin/ifconfig, and requires root but the effort has been made to obsolete it. Don't change, what doesn't need to change.&lt;br /&gt;
&lt;br /&gt;
=== /etc/resolv.conf depreciated ===&lt;br /&gt;
All you should need for DNS is a one line text file that points to a DNS server. Put that in /etc/resolv.conf. The simplicity of that is a threat to more obtuse OS, therefore there will be an effort to complicate it. This raises the bar for entry level people to get started. Adding unnecessary complexity to Linux.&lt;br /&gt;
&lt;br /&gt;
=== Aptitude Descriptions ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
debian 8:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
aptitude show openssl&lt;br /&gt;
Package: openssl&lt;br /&gt;
State: installed&lt;br /&gt;
Automatically installed: no&lt;br /&gt;
Version: 1.0.2k-1~bpo8+1&lt;br /&gt;
Priority: optional&lt;br /&gt;
Section: utils&lt;br /&gt;
Maintainer: Debian OpenSSL Team &amp;lt;pkg-openssl-devel@lists.alioth.debian.org&amp;gt;&lt;br /&gt;
Architecture: amd64&lt;br /&gt;
Uncompressed Size: 1,090 k&lt;br /&gt;
Depends: libc6 (&amp;gt;= 2.15), libssl1.0.0 (&amp;gt;= 1.0.2~beta3)&lt;br /&gt;
Suggests: ca-certificates&lt;br /&gt;
Description: Secure Sockets Layer toolkit - cryptographic utility&lt;br /&gt;
 This package is part of the OpenSSL project's implementation of the SSL and TLS cryptographic protocols for&lt;br /&gt;
 secure communication over the Internet.&lt;br /&gt;
&lt;br /&gt;
 It contains the general-purpose command line binary /usr/bin/openssl, useful for cryptographic operations such&lt;br /&gt;
 as:&lt;br /&gt;
 * creating RSA, DH, and DSA key parameters;&lt;br /&gt;
 * creating X.509 certificates, CSRs, and CRLs;&lt;br /&gt;
 * calculating message digests;&lt;br /&gt;
 * encrypting and decrypting with ciphers;&lt;br /&gt;
 * testing SSL/TLS clients and servers;&lt;br /&gt;
 * handling S/MIME signed or encrypted mail.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
debian 10:&lt;br /&gt;
&lt;br /&gt;
aptitude show openssl&lt;br /&gt;
Package: openssl&lt;br /&gt;
Version: 1.1.1d-0+deb10u3&lt;br /&gt;
State: installed&lt;br /&gt;
Automatically installed: no&lt;br /&gt;
Multi-Arch: foreign&lt;br /&gt;
Priority: optional&lt;br /&gt;
Section: utils&lt;br /&gt;
Maintainer: Debian OpenSSL Team &amp;lt;pkg-openssl-devel@lists.alioth.debian.org&amp;gt;&lt;br /&gt;
Architecture: amd64&lt;br /&gt;
Uncompressed Size: 1,495 k&lt;br /&gt;
Depends: libc6 (&amp;gt;= 2.15), libssl1.1 (&amp;gt;= 1.1.1)&lt;br /&gt;
Suggests: ca-certificates&lt;br /&gt;
Description: Secure Sockets Layer toolkit - cryptographic utility&lt;br /&gt;
&lt;br /&gt;
Homepage: https://www.openssl.org/&lt;br /&gt;
Tags: implemented-in::c, interface::commandline, protocol::ssl, role::program, scope::utility, security::cryptography,&lt;br /&gt;
      security::integrity, use::checking&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Ubuntu==&lt;br /&gt;
&lt;br /&gt;
=== Dropping Support for i386 ===&lt;br /&gt;
Some distributions are dropping intel 32-bit support. With one fell swoop, hundreds of thousands of laptops and desktops made before 2006 and 2007 lost the ability to use modern OS. EDIT: this was taken back, temporarily. It stands, that some OS must support 32 bit i386, otherwise a lot of devices will be headed to landfills.&lt;br /&gt;
&lt;br /&gt;
=== Setting up Networking has become more complicated ===&lt;br /&gt;
What was (/etc/networking/interfaces):&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
auto eth0&lt;br /&gt;
iface eth0 inet static&lt;br /&gt;
address 10.0.0.100&lt;br /&gt;
netmask 255.255.255.0&lt;br /&gt;
gateway 10.0.0.1&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Example taken direct from http://web.archive.org/web/20150916101112/https://help.ubuntu.com/lts/serverguide/network-configuration.html   For DNS, a one liner in /etc/resolv.conf will suffice.&lt;br /&gt;
&lt;br /&gt;
Now is (w/netplan.io)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
network:&lt;br /&gt;
  version: 2&lt;br /&gt;
  renderer: networkd&lt;br /&gt;
  ethernets:&lt;br /&gt;
    eth0:&lt;br /&gt;
      addresses:&lt;br /&gt;
        - 10.10.10.2/24&lt;br /&gt;
      gateway4: 10.10.10.1&lt;br /&gt;
      nameservers:&lt;br /&gt;
          search: [mydomain, otherdomain]&lt;br /&gt;
          addresses: [10.10.10.1, 1.1.1.1]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Example direct from http://web.archive.org/web/20190905160853/https://help.ubuntu.com/lts/serverguide/network-configuration.html&lt;br /&gt;
&lt;br /&gt;
===A better solution===&lt;br /&gt;
A solution is:&lt;br /&gt;
* whatever is used must be as simple, or simpler than before, as long as everything needed is included&lt;br /&gt;
* aim to keep interfaces similar when possible, as familiarity will increase efficiency&lt;br /&gt;
Look what ifupdown-ng did:&lt;br /&gt;
https://github.com/ifupdown-ng/ifupdown-ng/blob/master/doc/ADMIN-GUIDE.md&lt;br /&gt;
Their network interfaces is not more complex like netplan, but actually simpler. Yet it retains a lot of previous functionality, which means admins won't have to relearn everything. The new example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
auto eth0&lt;br /&gt;
iface eth0&lt;br /&gt;
    use dhcp&lt;br /&gt;
auto eth1&lt;br /&gt;
iface eth1&lt;br /&gt;
    address 203.0.113.2/24&lt;br /&gt;
    gateway 203.0.113.1&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
So here static is implied (which is either good or bad, depending on how you view it, and dhcp&lt;br /&gt;
is explicitly mentioned. Yet the term inet has been dropped (what does that even mean?). To be&lt;br /&gt;
honest it's mostly the same. A better comparison for what netplan.io should've been would be like comparing openvpn to wireguard. There is a great leap. The latter is extremely simple, yet doesn't omit anything required. Configuration is kept at a minimum. It's a tool that gets out of your way and lets you create the VPN without worrying about how to use the tool itself. Netplan.io adds bulk and bloat that makes it a difficult tool to use. If only for its verbose config files. The more switches you have to change, the more complex the tool.&lt;br /&gt;
&lt;br /&gt;
But is a new interfaces file even necessary? Is it change for the sake of change?&lt;br /&gt;
&lt;br /&gt;
===SystemD fail===&lt;br /&gt;
Once upon a time there were many different GNULinux distributions. All of them had their own init system and kernel and programs. But that was too difficult for the gubermints to break into. So they devised a plan: &amp;quot;What if we made a single program that ran on every computer, so it would be easy for us to break in?&amp;quot;. Thus the Intel ME was designed. Oh, and systemd too. They're basically the same idea. If every computer is the same, it makes the three letter agencies jobs easier.&lt;br /&gt;
&lt;br /&gt;
That's one angle. For other angles, see without-systemd.org&lt;br /&gt;
&lt;br /&gt;
====Reboot fail====&lt;br /&gt;
[[File:Systemd_Unable_To_Reboot.webm|thumb|A demonstration of Ubuntu and Systemd being unable to reboot the computer within a reasonable amount of time. It takes 5-10 minutes for reboot to occur. Keep in mind, that this init has been on this distribution for years now (from 16.04, so 2016-2020). Sysvinit does not have this problem, and reboots within 10-20 seconds. Note that this is a remote ssh session.]]&lt;br /&gt;
&lt;br /&gt;
In Ubuntu 19.04, reboot can take upwards of 5-10 minutes to actually reboot the computer. Note that this occurs in only SystemD based distributions. A similar Debian (9 or 10) w/sysvinit reboots within 10-15 seconds.&lt;br /&gt;
&lt;br /&gt;
I thought I would test systemd, so I installed Zoneminder on Ubuntu 19.04, and it demonstrates this problem. After witnessing the lifeforce of my computer being ripped out by this init, I threw the towel in and installed Devuan.&lt;br /&gt;
&lt;br /&gt;
For the record, I also noticed the system to run noticeably slower. CCTV is a good benchmark for a server, as it involves a lot of CPU usage, unlike many file servers, or db servers.&lt;br /&gt;
&lt;br /&gt;
====Example Error when Trying to Reboot====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
user@host:~$ systemctl reboot&lt;br /&gt;
Error getting authority: Error initializing authority: Error sending credentials: Error sending message: Broken pipe (g-io-error-quark, 44)&lt;br /&gt;
Failed to set wall message, ignoring: Failed to activate service 'org.freedesktop.login1': timed out (service_start_timeout=25000ms)&lt;br /&gt;
Failed to reboot system via logind: Connection timed out&lt;br /&gt;
Failed to start reboot.target: Connection timed out&lt;br /&gt;
See system logs and 'systemctl status reboot.target' for details.&lt;br /&gt;
It is possible to perform action directly, see discussion of --force --force in man:systemctl(1).&lt;br /&gt;
user@host:~$&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
And it will now take my machine 5-10 minutes to reboot.&lt;br /&gt;
&lt;br /&gt;
====External Links====&lt;br /&gt;
* [https://www.youtube.com/watch?v=RDKaFJmB254 LinuxCNC FAIL]: LinuxCNC broken because systemd can't do NTP right. In 2019/2020: Years after it is the default init...&lt;br /&gt;
* [https://nosystemd.org Nosystemd.org]: More details on why this init is bad.&lt;br /&gt;
&lt;br /&gt;
=== Udev requires reboots after Ubuntu 14 ===&lt;br /&gt;
When I started using Linux distributions one of the things I noticed was how well updates were handled, compared to proprietary software. No forced reboots, no update screens that leave the user waiting. You can use your computer while it's updating. This statement (&amp;quot;Linux never needs to reboot when it updates&amp;quot;) changed with udev requiring a reboot in Debian 8 or 9 occasionally (However, it's still extremely rare).&lt;br /&gt;
&lt;br /&gt;
==Misc==&lt;br /&gt;
=== GIMP 2.10 Icons and Theme Disaster ===&lt;br /&gt;
For reference see:&lt;br /&gt;
https://www.gimp.org/release-notes/gimp-2.10.html&lt;br /&gt;
&lt;br /&gt;
A light grey thread with colourful icons that transmit information quickly has been turned to a dark grey (read: hard to see) theme with a mass of all-looking-the-same grey icons that not only reinvent how you find the tool you wanted, it also fails to transmit information as effectively. If color tv is good, black and white is better?&lt;br /&gt;
&lt;br /&gt;
I consider this software on watch. As of now you can revert to the legacy (they call it 'legacy' instead of classic. Interesting word choice. Legacy implies depreciation. Classic implies value) so its ok, for now. But if these all-looking-the-same monochrome icons become default, it will be a regression.&lt;br /&gt;
&lt;br /&gt;
=== Mozilla Shuts Down IRC ===&lt;br /&gt;
 https://wiki.mozilla.org/IRC&lt;br /&gt;
Would you like some support for your mozilla? Just use your social media acct to login to our great matrix (whatever the hell that is) server.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Device Tree Bindings ===&lt;br /&gt;
ARM. Sounds like a good idea, except you need a different ISO for each single ARM CPU. Unlike the intel i386 which you can use one single ISO for ANY desktop/laptop.&lt;br /&gt;
&lt;br /&gt;
ARM is fail. DTB is busy work, and fail.&lt;br /&gt;
&lt;br /&gt;
This is one reason why Android is a failure.&lt;br /&gt;
&lt;br /&gt;
It looks like unfortunately that RISCV will also follow this path.&lt;br /&gt;
https://forums.sifive.com/t/will-riscv-avoid-the-linux-mainlining-mess-that-arm-had/1615&lt;br /&gt;
&lt;br /&gt;
https://unix.stackexchange.com/questions/399619/why-do-embedded-systems-need-device-tree-while-pcs-dont&lt;br /&gt;
&lt;br /&gt;
https://github.com/riscv/riscv-device-tree-doc&lt;br /&gt;
&lt;br /&gt;
EOMA68 devs have abandoned RISCV in favor of IBM's power CPU. Perhaps this is the right choice. RISCV may end up being not-worth-the-effort.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
quote&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Many embedded systems use less fancy buses that don't support enumeration. This was true on PC up to the mid-1990s, before PCI overtook ISA. Most ARM systems, in particular, have buses that don't support enumeration. This is also the case with some embedded x86 systems that don't follow the PC architecture. Without enumeration, the operating system has to be told what devices are present and how to access them. The device tree is a standard format to represent this information.&lt;br /&gt;
&lt;br /&gt;
The main reason PC buses support discovery is that they're designed to allow a modular architecture where devices can be added and removed, e.g. adding an extension card into a PC or connecting a cable on an external port. Embedded systems typically have a fixed set of devices¹, and an operating system that's pre-loaded by the manufacturer and doesn't get replaced, so enumeration is not necessary.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Well guess what - It's necessary now.&lt;br /&gt;
&lt;br /&gt;
===Raspberry Pi OS Sells Out Users to Proprietary Software via Telemetry===&lt;br /&gt;
&lt;br /&gt;
In 02/2021, Raspberry Pi OS (silently, and without warning) added an MS repo to APT, the package manager. Now each apt-get update will ping this demon corporation, letting them know that there is an RPI user at that IP address. The community is upset. The shills do damage control. Money corrupts. &lt;br /&gt;
&lt;br /&gt;
Shame.&lt;br /&gt;
&lt;br /&gt;
Ref: https://www.cyberciti.biz/linux-news/heads-up-microsoft-repo-secretly-installed-on-all-raspberry-pis-linux-os/&lt;br /&gt;
&lt;br /&gt;
{{GNU\Linux}}&lt;/div&gt;</summary>
		<author><name>Adminguy</name></author>
	</entry>
</feed>