FastAPI docker-compose demo

60 min read
---
# ######################################################################
# pypiserver docker-compose examples
# ######################################################################
# The below examples illustrate different ways that pypiserver may be
# configured with docker-compose (and by extension, with Docker) to
# serve your python packages.
#
# Most of the configuration options detailed below can be mixed and
# matched as desired.
# ######################################################################

version: "3.3"

services:

    # ##################################################################
    # Default
    # ##################################################################
    # The default configuration serves packages from the /data/packages
    # directory inside the container. This directory is mounted as a
    # volume in the Dockerfile, so it will be persisted, as long as you
    # do not remove it with `docker-compose down -v` or
    # `docker volume rm`.
    # ##################################################################

    pypiserver-default:
        image: pypiserver/pypiserver:latest
        ports:
            - "8080:8080"

    # ##################################################################
    # Authenticated
    # ##################################################################
    # This config uses a locally created .htpasswd file to authenticate
    # access to pypiserver. We assume our .htpasswd file is in a local
    # directory `./auth`, which we mount to `/data/auth` in the
    # container, and update the `command` from the Dockerfile to look
    # for that file for authentication. Note that because we are
    # overriding the default `command`, which tells pypiserver where to
    # serve packages from, we need to include that part of the command
    # in addition to our authentication information.
    # ##################################################################

    pypiserver-authenticated:
        image: pypiserver/pypiserver:latest
        volumes:
            - type: bind
              source: ./auth
              target: /data/auth
        command: -P /data/auth/.htpasswd -a update,download,list /data/packages
        ports:
            - "8081:8080"

    # ##################################################################
    # Serve local packages
    # ##################################################################
    # This config allows us to manage our package directory locally,
    # rather than in a volume managed directly by docker. Note that
    # especially if running from a Mac, this may cause performance
    # degradations, which can be worked around by using the `consistency`
    # setting if desired. Here, we mount a local `./packages` directory
    # to `/data/packages`, overriding the standard volume.
    # ##################################################################

    pypiserver-local-packages:
        image: pypiserver/pypiserver:latest
        volumes:
            - type: bind
              source: ./packages
              target: /data/packages
        ports:
            - "8082:8080"

    # ##############################################################################
    # Authenticated and serve local packages via HTTPS using Traefik
    # ##############################################################################
    # This one combines the two configurations above and uses Traefik for HTTPS and
    # with automatic HTTP redirect.
    # Remember to change "your.domain.com" and "[email protected]" with your domain
    # and email address respectively.
    #
    # The pypiserver will be available at: https://your.domain.com
    # The Traefik dashboard will be available at: https://your.domain.com/dashboard/
    #
    # A Traefik user can be added using the htpasswd tool:
    #   htpasswd -sc traefik/usersfile username
    # ##############################################################################

    pypiserver-https:
        image: pypiserver/pypiserver:latest
        volumes:
            - type: bind
              source: ./auth
              target: /data/auth
            - type: bind
              source: ./packages
              target: /data/packages
        command: -P /data/auth/.htpasswd -a update,download,list /data/packages
        labels:
            # Expose container to Traefik
            - "traefik.enable=true"

            # Configure the route
            - "traefik.http.routers.flask.rule=Host(`your.domain.com`)"
            # - "traefik.http.routers.flask.rule=Host(`pypi.docker.localhost`)"
            - "traefik.http.routers.flask.entrypoints=websecure"
            - "traefik.http.routers.flask.tls=true"
            - "traefik.http.routers.flask.tls.certresolver=leresolver"
    traefik:
        image: traefik:v2.1
        volumes:
            - "/var/run/docker.sock:/var/run/docker.sock:ro"
            - "./traefik:/etc/traefik:ro"
            - "./traefik/acme:/etc/traefik/acme"
        command:
            - "--entrypoints.web.address=:80"
            - "--entrypoints.websecure.address=:443"
            - "--providers.docker=true"
            - "--providers.docker.exposedbydefault=false"
            - "--api.dashboard=true"
            - "[email protected]"
            - "--certificatesresolvers.leresolver.acme.storage=/etc/traefik/acme/acme.json"
            - "--certificatesresolvers.leresolver.acme.httpChallenge=true"
            - "--certificatesresolvers.leresolver.acme.httpChallenge.entrypoint=web"
        ports:
            - "80:80"
            - "443:443"
        labels:
            # Expose container to Traefik
            - "traefik.enable=true"

            # Dashboard
            - "traefik.http.routers.traefik.rule=Host(`your.domain.com`) && (PathPrefix(`/api`) || PathPrefix(`/dashboard`))"
            # - "traefik.http.routers.traefik.rule=Host(`traefik.docker.localhost`)"
            - "traefik.http.routers.traefik.entrypoints=websecure"
            - "traefik.http.routers.traefik.tls=true"
            - "traefik.http.routers.traefik.tls.certresolver=leresolver"
            - "traefik.http.routers.traefik.service=api@internal"
            - "traefik.http.routers.traefik.middlewares=authtraefik"
            - "traefik.http.middlewares.authtraefik.basicauth.usersfile=/etc/traefik/usersfile"

            # Global redirect to HTTPS
            - "traefik.http.routers.http-catchall.rule=hostregexp(`{host:.+}`)"
            - "traefik.http.routers.http-catchall.entrypoints=web"
            - "traefik.http.routers.http-catchall.middlewares=redirect-to-https"

            # Middleware redirect
            - "traefik.http.middlewares.redirect-to-https.redirectscheme.scheme=https"