
Ask HN: What has your experience been with using Docker for local development - sidcool
I am just beginning development in local with Docker containers.  So far it&#x27;s been a lot of work to set up Hot code reload, DB persistence etc. It takes up a lot of memory.<p>What has your experience been?  What tips, tricks etc. helped you?
======
atmosx
Hm, can you describe your workflow? I think your doing something wrong. Docker
is not a substitute for automated testing triggered by file changes.

On the other hand spinning up a redid/MySQL is straight forward with docker.

Any kind of virtualization will consume memory. I think you need at least 8GB
of ram for a dev machine, but everything d pends on details.

------
zhangys
1\. Use docker-compose
([https://docs.docker.com/compose/](https://docs.docker.com/compose/)) The
compose file can save you a lot of trouble in dealing with the detailed setup.
2\. Use alpine, for instance, when python needed, alpine version is much
smaller than running a full instance.

------
imauld
Do you actually need hot reload? I structure my images like so to avoid long
build times for images:

\- Base image that just has the run time (usually an alpine image for Python,
Java etc). These are left as generic as possible so they can be reused easily.
This is usually an official image however you can also make your own.

\- Dependencies image where the application dependencies that are unlikely to
change are installed. For Python this means creating a virtual env and
installing the required packages. Any system packages for Python that aren't
likely to change (cffi, libjpeg, openssl etc) will go here as well.
Dockerfile.base in the example below.

\- Application image. Copy in the code/configuration for Python or the binary
for Java. If you are developing on Mac and compiling for Linux you can do this
with a multistage build so you can be sure anything you compile will be for
the right architecture.

Examples:

Dockerfile.base

    
    
        # Alpine images are great because they are small but if you are still early in development
        # you may want to use Debian/Ubuntu/Jessie as they are a more "complete" OS and will make it
        # to debug inside the container. Alpine linux doesn't even come with bash (it has sh)so it can be difficult
        # to figure out what is wrong if you encounter some weirdness
        FROM python:alpine3.6
    
        You can obviously put this anywhere but this usually what I do
        RUN mkidr /app
        COPY requirements.txt /app/requirements.txt
        RUN python3 -m venv /venv && \
            /venv/bin/pip install -r /app/requirements.txt
    

Dockerfile

    
    
        # Image created from previous example
        FROM base:0.0.1
    
        # Assuming your Dockerfile is a sibling to your src directory
        COPY ./your_package /app/
    

And that's it. Unless your project is a huge monolith new images should be
rebuilt very quickly. This takes heavy advantage of Docker's layer caching.
Generally only the very last thing that is built will be changing so you won't
have to rebuild the previous layers. I usually don't include CMD, RUN, or
ENTRYPOINT in my Dockerfiles. I leave that up to whatever I'm using to run
them, Docker Compose or Kubernetes. I also leave environment configuration up
to the tool doing the running as well. Things like environment variables,
exposed ports and secrets are usually better handled by these tools than by
the image itself. Volume mounts are also best setup via compose or k8s rather
than being baked in to the image. Example:

docker-compose.yaml

    
    
        version: "3"
        services:
          yourapp:
            # The image we built earlier
            image: sidcool/yourapp:app-0.1.0
            # Expose port 8080 of the container on port 8080 of the host
            ports:
              - "8080:8080"
            # How to run the app
            command: "/venv/bin/gunicorn -c app/config.py app.server:app"
            # Lets compose know that this service needs the db service to start
            links:
              - db
          db:
            image: postgres:10
            # Use a volume to persist DB data between container restarts
            volumes:
              - db-data:/var/lib/postgresql/data
        volumes:
          db-data:
    
    
    

However if hot reload is a requirement you can achieve that with mounting the
code inside the container via volume mount. That way you can edit the code on
your host with whatever tools your used to and the changes will be reflected
in the container fairly quickly. This adds a bit of complexity and can be slow
if your copying large numbers of files over.

