Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I keep my database, but change the code in docker-compose?

I have a Python+MySQL webservice running on a Digital Ocean droplet in production. When I updated the code in the project on my local machine, I want the changes to take place in the droplet (in production) as well. So I do the following to deploy:

$ ssh [email protected]
# cd project
# git pull
# docker-compose down
# docker-compose build
# docker-compose up -d

After this, my database is empty. It has none of my tables in it. How can I update the code which is running, but not lose the data?

My Code

Project structure

.
├── db
├── docker-compose.yml
└── web
    ├── Dockerfile
    ├── project
    │   ├── app.py
    │   ├── __init__.py
    │   ├── blueprint1
    │   ├── blueprint2
    │   ├── models.py
    │   ├── static
    │   ├── templates
    │   └── _version.py
    ├── Makefile
    ├── migrations
    ├── README.md
    ├── setup.cfg
    ├── setup.py
    ├── start.sh
    ├── tests
    └── tox.ini

docker-compose.yml

version: "2"
services:
  db:
    image: mysql:5.7
    ports:
      - "32000:3306"
    environment:
      MYSQL_DATABASE: ***
      MYSQL_ROOT_PASSWORD: ***
    volumes:
      - ./db:/docker-entrypoint-initdb.d/:ro
  app:
    build: ./web
    links:
      - db
    ports:
      - "5000:5000"
    environment:
      MYSQL_PORT: 32000

Dockerfile

FROM python:3.7-slim

# Copy projects code
RUN apt-get update && apt-get install -y git
COPY . /opt/app
WORKDIR /opt/app
RUN pip install -e . --no-cache-dir

# Start app
ENV ENV=prod
EXPOSE 5000
ENTRYPOINT ["sh", "start.sh"]
CMD ["/opt/app/start.sh"]

What I've tried

# This killed my data:
$ docker-compose up -d --build app

# This did NOT update the code in app:
# 1
$ docker-compose stop app && docker-compose up -d app
# 2
$ docker-compose up -d --no-deps --build app
like image 843
Martin Thoma Avatar asked Jan 01 '23 22:01

Martin Thoma


2 Answers

You have to create a named volume for your database like so

version: '3'

services:    
  mysql:
    image: mysql:5.7
    volumes:
      - mysql_data:/var/lib/mysql

volumes:
  mysql_data:

Now you can do safly run docker-compose stop or docker-compose down without losing your data on the mysql_data volume. Only when you run docker-compose down -v it will remove the volume as well.

You can see all your named volumes by running docker volume ls

Quick note: docker-compose is designed for development and not for production. You might want to consider a different strategy.

like image 70
Chris Avatar answered Jan 05 '23 14:01

Chris


  1. Create folder on host-machine
mkdir /data/mysql
  1. Start your MySQL in docker
  2. Copy database from running MySQL container in to host-machine
docker ps | grep mysql
docker cp <container_id>:/var/lib/mysql /data/mysql
  1. Make change in your docker-compose.yml
    volumes:
      - ./db:/docker-entrypoint-initdb.d/:ro
      - /data/mysql:/var/lib/mysql
  1. Restart all.
like image 42
Qteb Avatar answered Jan 05 '23 16:01

Qteb