You can submit a form on phproundtable.com with any ideas you have for topics that can be discussed on the podcast.
The last episode about Docker was Episode 48.
Brand new stickers are available (much smaller!), and will be sent out for the Developer Shout-Outs.
Discussion - The panel talks about...
Docker Compose vs. Docker
- You need to use Docker to figure out how Docker works. Start with this.
- Then you use Docker Compose, because you know how Docker works by this point, so it does most of the work for you.
- Docker Compose allows you to keep all of your configuration in a text file. With regular Docker, you need to use multiple commands to set everything up.
Minimum, you need:
- What container you are starting with (base container)
- Commands to set up your configuration / install things for you
When to use the
Docker command has multiple flags. For example:
-i - Interactive shell
-t - Allocate a tty
--rm - Remove container after you're done
Q: Why would you create it, only to delete it again after it's done?
- He generally has an Apache container, a MySQL container, and a couple of other containers that make the application work. Those you usually want to stay around. Don't
- Others (composer, unit tests, etc) you will
--rm ... you want to use them for something quick, but don't care about keeping them around (unlike the database container).
- Will often use
--rm when he's initially building his
- He can exec into a base container (or run it interactive), and have it delete itself afterwards.
- Once it's working how he wants it to and he's finished making rapid changes to his
Dockerfile, he can remove the
--rm flag. It's built-in garbage collection!
- When you stop a container, it still exists - it's just not running.
- If you never clean out those containers, you have this list of unused containers just hanging around in your system.
Image vs Container
- You build the image (state / like an OOP Class)
- Container is run from the image (instance / like an OOP Object)
- By running
--rm you are cleaning up the container, but the image still exists.
- When you make changes in your
Dockerfile to copy files into the image, you want to make sure you are rebuilding the image. Otherwise, when you rebuild the container, it won't have copied those files in because it's still using the old image.
Docker Compose commands
Docker Compose settings are saved inside the
docker-compose.yml file in your project root.
- BUILD - Build (or rebuild) the image.
docker up and
- UP - Bring the environment up. Creates containers and starts them.
- DOWN - Bring the environment down. Stops containers and removes them.
docker start and
- START - Starts services from existing containers.
- STOP - Stops services, but doesn't remove them.
docker up will usually do
docker build for you:
- If the image doesn't exist, it will detect this and will build the image for you, saving the need to run
docker build manually.
- If you've made changes to
docker-compose.yml, it should detect this and rebuild the image for you.
- If you've made changes to other files (e.g. your source code), it won't detect that and you need to run
docker build manually before you start it up again.
Notes about adding files:
- Copy/add files - takes place at build time, and adds them to the image.
- You can also use volumes, which is a way of adding files to the container at runtime.
- Official container for MySQL sets up the database on a volume. Since it's effectively mounted, the files end up on your disk.
Important distinction to make:
- UP - Creates containers and starts them.
- DOWN - Stops containers and removes them.
- START - Start container only.
- STOP - Stop container only.
So, to clarify:
- UP/DOWN = Full environment and stack.
- START/STOP = Just the container.
Project structure - best practices
With Docker version 2 & 3 - you can specify named volumes:
- You can make a volume that is mountable across multiple containers.
- Persistent outside of the containers, too.
- By defining a named volume in your configuration file, the data will persist between up/down commands.
There is a speed drop with Windows / macOS:
- Trying to access files from a Linux Docker container on your Windows or macOS system, it's slower. This is because the linux container boots up inside a VM.
- Docker runs underneath the host OS kernel, it's not actually a VM in and of itself.
- But since Windows / macOS are not linux, it bootstraps itself inside of a linux virtual machine.
- If you need to get to stuff on your host machine, you're effectively trying to put your host machine inside a virtual machine.
- The issue on macOS is that the layer it uses is very slow. Not an issue with Docker, it's an issue with the intermediate layer. Apple is working with Docker to speed that up.
- Windows seems to do slightly better than macOS in terms of speed for Linux containers.
- Linux is best of all for running Linux, because you don't need the virtualisation layer.
- You mainly see the speed drop for I/O heavy traffic. So applications that rely on heavy I/O will suffer most noticeably.
Docker in Production
Docker as a product has stabilised significantly over the years, and is now much easier to use. It's getting better and better, and a lot of the rough edges have been "shaved off".
- Build for production
- In your development environment, plug in what you need just for that environment.
- You only want certain runtime dependencies like Xdebug in the environment that you need them (development). They should not exist in the production environment.
You can stack multiple configuration files on top of each other:
- For example,
docker-compose.yml (production) and
- It will take the stuff in dev and then merge it into the production one.
Upcoming feature: Multi-stage builds:
- A single
Dockerfile that builds multiple images (i.e. production & development)
Multiple startup scripts:
- You can have two separate bash scripts, one that launches with production config, and another that launches with dev config.
- Each script can be used for a different entry point, and can do some different set up before starting the container.
Docker is greater for the state-less part of your application, i.e. your code.
Everything else should probably be pushed out to other services (Amazon RDS, Redis, etc).
You can use Docker Machine with Amazon / Digital Ocean, to set up your machine.
It allows you to run things from your local machine. You can run Docker Up regardless of whether you're working on your local environment, or your production environment, which is pretty nice.
Under the hood, Docker is pretty much just a HTTP API. The Docker command is literally just an API client!
A registry for storing your images. You can access public images, or you can pay to store your private images there.
On your docker server, you would then pull those images down from Docker Hub (or a similar service).
Updates could be as simple as:
- Stop container
- Docker Pull
- Start container
Allows you to run multiple instances quite easily, and will do the rolling release for you.
There are ways to set this up with EC2. ECS orchestration service is free, you just pay for the actual EC2 usage.
Accessing Docker via CLI
Q: Vagrant allows us to simply connect using
vagrant ssh. How do we do something similar with Docker?
- The main thing to remember is that Docker isn't a machine, it's a process. It spins up a process and then watches it.
- You can use something like
docker exec to spin up a second process in the same area, rather than SSHing into a machine.
- They might act like machines, but they're not. There's not actually a command-line process / ssh daemon running inside those containers, usually.
- If you change things in that container, you will lose it when you restart. The restarted container will go off the base image, so to make changes you should modify the image instead.
- Most containers expect to run as root, they don't expect another user to run inside of them. So it's not a good idea to set up additional users.
Sub-domains / TLS in Development
- Generally, don't bother. Just bind to a different port if you need multiple apps running at once.
- There are ways to get things like Let's Encrypt set up locally if you need it, but on a day-to-day basis it's usually not something the panel members worry about.
- You can run in the foreground and have it tail the logs for you, but using Ctrl+C afterwards is a little tricky.
- It's probably better to run it in the background (as a daemon) instead using
docker up -d, and then use the
docker logs --follow command to follow your logs.
- Docker most likely expects you to shut it down using
docker down, not
- If you want to get really fancy, you can push to Kibana, etc.
Sammy Kaye wraps up with