docker snippets

How to start a bash shell in Docker

Tagged docker, shell, bash  Languages bash

To start a bash shell in an already running container:

docker exec -it <container id/name> bash

To start a bash shell using an image of a container that is not running:

docker run -i -t --entrypoint /bin/bash <image id>

How to access a service running on the host from a docker container

Tagged rtfm, docker, host, ip, docker-compose, subnet, ufw, container  Languages bash

How to access a service running on the host from a docker container? Easy…

First, RTFM:

Linux (bridge network)

  1. Create a custom bridge network

You can also use the default bridge network.

  1. Make the docker container use the custom network

See network configuration in the docker compose example below.

  1. On the host make the service listen to the hosts IP address on the custom network

For example, change listen_addresses in postgresql.conf for PostgreSQL.

Example docker-compose.yml:

version: "3.8"
      - mynetwork
    env_file: ./mycontainer.env
        - subnet:

The docker container will be assigned an IP from the subnet.

Make sure the service is listening to the host’s IP address on the network which should be

Remember to allow the traffic in the firewall. See UFW example below:

# Check where the connection is coming from:
sudo dmesg
# Unblock the connections by source IP
sudo ufw allow in from "" to port 5432
# Or, unblock the connections by network name
sudo ufw allow in on <name of network> to port 5432


Host networking is not supported by MacOS. You can use an IP address alias instead or one of the host’s IP addresses.

Option 1: Using an IP address alias

We can use an IP address that does not resolve inside the container to access the host. Unresolved IP addresses are routed to the host for resolving.

First, create an alias:

sudo ifconfig lo0

Make Postgres listen to the address in postgresql.conf:

listen_addresses = 'localhost,'

Allow connections in pg_hba.conf:

host    all             all               trust

Restart PostgreSQL.

Option 2: Using an existing host IP address

Same as above except you don’t have to create an alias as the IP address already exists.

Run ifconfig -a on the host to list all IP addresses. Select one and see the instructions above.

Bad ideas

There are many other ways of achieving this, which are more or less bad ideas…

  • Option 1: docker hostnames

This option is mostly useful in development environments:

# Mac
ping docker.for.mac.localhost

# Windows

# Linux: use the Docker IP or the hosts external IP, see:
  • Option 2: host networking

This option is not a good idea if you plan on hosting many projects on the same server.

Note that it’s not possible to use host networking on Mac or Windows, only Linux:

The host networking driver only works on Linux hosts, and is not supported on Docker Desktop for Mac, Docker Desktop for Windows, or Docker EE for Windows Server.


Configure Docker to use a private container registry using a self-signed certificate

Tagged self-signed, registry, docker  Languages bash

How to configure Docker to use a private container registry using a self-signed certificate.

Tested on Docker version 18.09.4, build d14af54.

  • Copy self-signed certificate from the registry server to the docker server

On your laptop:

$ scp [email protected]://etc/ssl/certs/selfsigned.crt [email protected]://etc/ssl/certs/private-docker-registry.crt
  • Restart docker daemon

On the docker server:

$ sudo service docker restart
  • Login to the registry from the docker server

On the docker server:

sudo docker login -u christian registry-server
> WARNING! Your password will be stored unencrypted in /home/christian/.docker/config.json.

How to configure Kubernetes to pull images from a private Docker registry

Tagged kubernetes, private, registry, docker  Languages bash, yml

How to configure Kubernetes to pull images from a private Docker registry:

  • First configure Docker by following the steps outlined here:

  • Verify that the Docker configuration contains the authentication information
sudo cat ~/.docker/config.json
    "auths": {
        "<registry-server>": {
            "auth": "<hash>"
    "HttpHeaders": {
        "User-Agent": "Docker-Client/18.09.4 (linux)"
  • Base64 encode the config.json file
cat ~/.docker/config.json | base64 -w0 > config.base64.json
  • Create secret.yml and add the contents of config.base64.json to dockerconfigjson
apiVersion: v1
kind: Secret
 name: registrypullsecret
 .dockerconfigjson: <config.base64.json>
  • Import the secret into Kubernetes
kubectl create -f secret.yml && kubectl get secrets
  • Test that the secret was imported into Kubernetes
kubectl get secrets

Simple Dockerfile for Ruby on Rails applications

Tagged dockerfile, docker, rails, ruby  Languages bash
# Ruby on Rails Dockerfile
# ## Features:
# - Ruby
# - Puma
# - Yarn
# - Node
# - PostgreSQL
# ## Configuration
# ```bash
# mkdir .docker
# cat << EOF > .docker/
# RAILS_ENV=development
# DB_HOST=localhost
# DB_NAME=app_development
# DB_USER=app
# DB_PASS=password
# cat << EOF > .docker/
# RAILS_ENV=production
# DB_HOST=postgres
# DB_NAME=app_production
# DB_USER=app
# DB_PASS=password
# ```
# ## Usage
# ```bash
# $ docker build . -t <image name>
# # Development
# $ docker run --network=host --env-file=.docker/ <image name>
# # Production
# $ docker run -p 3000:3000 --env-file=.docker/ <image name>
# ```
FROM ruby:2.6.3

# Add Yarn to apt
# RUN curl -o- -L | bash
RUN curl -sS | apt-key add -
RUN echo "deb stable main" | tee /etc/apt/sources.list.d/yarn.list

# Install dependencies
RUN apt-get update -qq && apt-get install -y build-essential libpq-dev nodejs yarn

# Don't run as root
RUN useradd --user-group -m --home /app --shell /bin/false app
RUN chown app:app /app
RUN chmod -R 740 /app
USER app

# Set working dir


# Set ENV variables

# Add and cache Ruby & Javascript dependencies
COPY --chown=app Gemfile Gemfile
COPY --chown=app Gemfile.lock Gemfile.lock
ADD package.json yarn.lock /tmp/
# Install Ruby and Javascript dependencies
RUN gem install bundler:2.0.2
RUN bundle install --jobs 20 --retry 5 --with=$RAILS_ENV --deployment
RUN yarn install

# Add project files
COPY --chown=app . .
# Precompile assets
RUN bundle exec rake assets:precompile

RUN mkdir -p log tmp/pids

CMD ["bundle", "exec", "puma", "-C", "config/puma.rb"]

UFW + Docker = No firewall

Tagged elasticsearch, gotcha, iptables, ufw, wtf, docker  Languages 

TLDR: Docker can and will override existing iptable rules and expose your services to the Internet

This means you have to think twice when installing Docker on a machine that is only protected by an iptables-based firewall such as UFW. You might think you are protected by your firewall, but you very likely are not. This is probably one of the more common reasons why Elasticsearch servers, which are unprotected by default, are exposed to the internet.

For details, see:

Solution 1: External firewall

One solution is to use a firewall provided by the hosting provider (DO, AWS, GCP, etc.).

Solution 2: Disable Docker’s iptables “feature”

Disable iptables in Docker by adding the following switch:


Solution 2: Listen on private IPs

This is perhaps the easiest to implement and easiest to forget: expose your containers and services on one of the following private IP address ranges:

  • to
  • to
  • to

Note that binding to will not work with Docker Swarm.

How to set the environment variables in a cron script (Docker)

Tagged docker, env, crontab, environment, docker-compose, cron  Languages bash

To give your cron script access to the same environment variables as the Docker container, you can read and export the environment variables for the PID 1 process in your script:

crontab -l
* * * * * /app/


#!/usr/bin/env bash
# Read the environment variables for the main process (PID 1) running in the Docker container:
export $(xargs -0 -a "/proc/1/environ")

python3 -m $1