Dr Rob Lang
Dr Rob Lang

Reputation: 6883

Visual Studio Docker Tools how to force a container rebuild from scratch

I am using docker-compose in Visual Studio 2017 (tool version 0.41) to build two images, a ASP.NET Core API container and a PostgreSQL container. I ran the Docker-Compose project and everything worked OK - I could access the database from the Api container.

I would now like to change the PostgreSQL environment variables POSTGRES_USER, POSTGRES_PASSWORD and POSTGRES_DB to new values like below:

docker-compose.yml:

services:
    mcodatabase:
        image: mcodatabase
        build:
        context: ./Data
        dockerfile: Dockerfile
        restart: always
        ports:
        - 5432:5432
        environment:
        POSTGRES_USER: mcodevuser
        POSTGRES_PASSWORD: password
        POSTGRES_DB: mcodev
        volumes:
        - postgresdata:/var/lib/postgresql/data
        networks:
        - mconetwork
    mcoapi:
        image: mcoapi
        build:
        context: ./Mco.Api
        dockerfile: Dockerfile
        ports:
        - 56107:80
        links:
        - mcodatabase
        depends_on:
        - "mcodatabase"
        networks:
        - mconetwork

    volumes:
    postgresdata:

    networks:
    mconetwork:
        driver: bridge

However, as I understand it, the images have already been created. I want to begin again with the database image mcodatabase.

Here are my images:

c:\Projects\v4>docker images
REPOSITORY             TAG                 IMAGE ID            CREATED             SIZE
mcodatabase            dev                 96c9ba7509ed        2 hours ago         267 MB
mcoapi                 dev                 f238b18ab9bb        26 hours ago        288 MB
microsoft/aspnetcore   1.1                 b186ab38f718        8 days ago          288 MB
postgres               latest              ff0943ecbb3c        13 days ago         267 MB
d4w/nsenter            latest              9e4f13a0901e        7 months ago        83.8 kB

Is there a way to do this with the tool?

If not, is there any problem simply removing the images using >docker rmi mcodatabase:dev. When I next build, will docker-compose understand that it doesn't have that image and build it afresh?

Upvotes: 5

Views: 11239

Answers (3)

Dr Rob Lang
Dr Rob Lang

Reputation: 6883

There is also a command line solution.

To refresh the PostgreSQL database environment variables, you need to remove the database container and its volume. When Visual Studio next runs the docker-compose project, it will recreate the database container and its associated volume with a new 'install' of PostGres and updated environment variables. You will lose your data, so backup first!

Here is the starting point, two containers: one for the ASP.NET Core container (mcoapi) and one for the database (mcodatabase). Mco is the acronym for our company. \v4 is the root of my Visual Studio solution but these commands can be run from anywhere as we're not using the docker-compose command line (see why below).

C:\Projects\v4>docker ps -a
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                                          NAMES
809b90e22290        mcoapi:dev          "tail -f /dev/null"      About an hour ago   Up About an hour    0.0.0.0:32776->80/tcp, 0.0.0.0:56107->80/tcp   dockercompose320715364_mcoapi_1
86d9036daccf        mcodatabase:dev     "docker-entrypoint..."   About an hour ago   Up About an hour    0.0.0.0:5432->5432/tcp                         dockercompose320715364_mcodatabase_1

First, I stop the containers. I am using the first two digits of the CONTAINER_ID as a shorthand.

C:\Projects\v4>docker stop 80
C:\Projects\v4>docker stop 86

Now I remove the containers. I need to remove both because I believe they are both using the same docker volume.

C:\Projects\v4>docker rm 80
C:\Projects\v4>docker rm 86

I now have no containers.

C:\Projects\v4>docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES

I can now remove the volume where the database is stored.

BEFORE YOU DO, BACKUP ANY DATA YOU NEED, THIS WILL WIPE THE DATABASE!

Next, I check to see what volumes have been mounted:

C:\Projects\v4>docker volume ls
DRIVER              VOLUME NAME
local               dockercompose320715364_postgresdata

I could now remove it by using >docker volume rm dockercompose320715364_postgresdata but I prefer volume prune, which removes volumes that aren't used anymore. If I've forgotten to remove a container, I'll soon know. Give y at the warning.

C:\Projects\v4>docker volume prune
WARNING! This will remove all volumes not used by at least one container.
Are you sure you want to continue? [y/N] y
Deleted Volumes:
dockercompose320715364_postgresdata

Total reclaimed space: 45.95 MB

We can now change the environment variables in docker-compose.yml. All I've changed in the below is the contents under environment:.

version: '2'

services:
mcodatabase:
    image: mcodatabase
    build:
    context: ./Data
    dockerfile: Dockerfile
    restart: always
    ports:
    - 5432:5432
    environment:
    POSTGRES_USER: myNewUser
    POSTGRES_PASSWORD: myNewPassword
    POSTGRES_DB: myNewDb
    volumes:
    - postgresdata:/var/lib/postgresql/data
    networks:
    - mconetwork

[snip for brevity]

I now run the docker-compose project in Visual Studio and the database container is recreated with the new values.

Why I didn't call docker-compose from the command line

It's possible to use docker-compose down like commands on the command line to perform similar tear downs but I found the command line more complex to get right because it includes all the different yml files that Visual Studio needs. For example, the up that is called from the Visual Studio tool is:

docker-compose -f "C:\Projects\v4\docker-compose.yml" -f "C:\Projects\v4\docker-compose.override.yml" -f "C:\Projects\v4\docker-compose.vs.debug.yml" -p dockercompose320715364 up -d

This was less intuitive than doing it manually. If someone knows a better way, I'm all ears!

Upvotes: 6

Weida Zhao
Weida Zhao

Reputation: 219

First of all, container tools 1.0 (previously called Docker Tools) is built in VS 2017. You don't need to install 0.41. In fact, 0.41 only supports VS 2015. Please do NOT install 0.41 on VS 2017 even if it is possible.

Visual Studio Docker Tools how to force a container rebuild from scratch

Running 'clean' against the docker-compose.dcproj in Visual Studio will do docker-compose down for you. If you want to rebuild images, switch to 'Release' configuration and run 'rebuild' against docker-compose.dcproj.

enter image description here

Upvotes: 18

Myles Keating
Myles Keating

Reputation: 180

An idea that helped me to understand container images vs containers themselves is to think of container images as binaries and an individual container as a process.

The documentation on docker compose files may help

Upvotes: -1

Related Questions