This post picks up from where Configuring DGDocker2 left off. In it I will establish a workflow to setup a “Dockerized” server complete with Traefik, Portainer, and Who Am I. It should be relatively easy to add additional non-static services to any server that is initially configured using this package. For “static” servers have a look at post 008 docker-bootstrap Workflow .

Capture As a Project

Picking up from the end of Configuring DGDocker2, my first step on the dgdocker2 server was to move everything into a single subdirectory of /opt; I called the new directory dockerized-server, like so:

mkdir -p /opt/dockerized-server
mv -f /opt/traefik /opt/dockerized-server/traefik
mv -f /opt/portainer /opt/dockerized-server/portainer
mv -f /opt/whoami /opt/dockerized-server/whoami

Then, I built a new /opt/dockerized-server/docker-compose.yml file to launch Traefik, Portainer, and WhoAmI.

version: "3"

#### docker-compose up -d


    image: traefik:1.7.14-alpine
    command: --configFile=/traefik.toml
    container_name: traefik
    restart: always
      - "80:80"
      - "443:443"
      - /var/run/docker.sock:/var/run/docker.sock:ro
      - /opt/dockerized-server/data/traefik.toml:/traefik.toml
      - /opt/dockerized-server/data/acme.json:/acme.json
      - web
      - traefik.enable=true
      - ""
#      - "traefik.frontend.rule=PathPrefixStrip:/traefik"
#      - "traefik.frontend.redirect.regex=^(.*)/traefik$$"
#      - "traefik.frontend.redirect.replacement=$$1/traefik/"
#      - "traefik.frontend.rule=PathPrefix:/traefik;ReplacePathRegex: ^/traefik/(.*) /$$1"
      - traefik.port=8080

    image: portainer/portainer
    container_name: portainer
    command: --admin-password "$$2y$$05$$pJEzHJBzfoYYS7/hGAedcOP8XdsqNXE7j.LHFBVjueASOqOvvjGOy" -H unix:///var/run/docker.sock
    # command: -H unix:///var/run/docker.sock --no-auth
      - web
      - internal
      - "9010:9000"     ## Remapped to avoid conflicts on systems/servers with portainer already running.
      - /var/run/docker.sock:/var/run/docker.sock
      - portainer-data:/data
      - traefik.port=9000
      - traefik.enable=true
      - "traefik.frontend.rule=PathPrefixStrip:/portainer"
      - "traefik.frontend.redirect.regex=^(.*)/portainer$$"
      - "traefik.frontend.redirect.replacement=$$1/portainer/"
      - "traefik.frontend.rule=PathPrefix:/portainer;ReplacePathRegex: ^/portainer/(.*) /$$1"

    image: emilevauge/whoami
      - "traefik.enable=true"
      - ""
      - "traefik.frontend.passHostHeader=true"
      - "traefik.frontend.headers.SSLRedirect=true"
      - web
      - internal

    external: true
    external: false


Use the Let’s Encrypt Staging Server

To avoid additional rate-limit issues with Let’s Encrypt, I’m going to switch to using their “staging” server. That requires the addition of this snippet to our /opt/dockerized-server/traefik/traefik.toml file:

# CA server to use
# Uncomment the line to run on the staging Let's Encrypt server
# Leave comment to go to prod
# Optional
caServer = ""

A Fresh Start

Now, all that’s required to spin up the new server with the aforementioned parts, in this case on dgdocker2, is a command sequence like this:

# Clean up first!
docker stop $(docker ps -q); docker rm -v $(docker ps -qa); docker image rm -f $(docker image ls -q); docker system prune --force;
# Navigate into the project
cd /opt/dockerized-server
# Launch
docker network create web
docker-compose --log-level DEBUG up -d

A Quick Test

Since the above command sequence produced no errors, it’s time to test what we have. The expectation is that our three services should now be running on dgdocker2, and they should respond in any web browser at the addresses shown here:

Confirmed! All of the above are working properly, albeit with invalid/temporary certs (due to Let’s Encrypt rate limiting).

Pushing to GitHub

No project is complete these days without a GitHub component (or something very similar). So, my next step was to create a new GitHub repository at, and push the contents of my dgdocker2:/opt/dockerized-server directory to it, like so:

git init
git add -A
git commit -m "Initial commit"
git remote add origin
git push -u origin master

Back to Configuring DGDocker2

At this point you might return to Configuring DGDocker2 where I’ll finally add Omeka-S to dgdocker2.

And that’s a wrap… until next time. 😄