16

Everytime I restart my ec2 server I have to do: sudo systemctl start docker and then docker-compose up -d to launch all my containers.
Would there be a way to automatically run these two commands at the start of the instance? I have read this answer and I think ideally I would like to know how to do that:

Create a systemd service and enable it. All the enabled systems services will be started on powering.

Do you know how to create such systemd service?

[EDIT 1]: Following Chris William's comment, here is what I have done:

Thanks Chris, so I created a docker_boot.service with the following content:

[Unit]
Description=docker boot
After=docker.service

[Service]
Type=simple
Restart=always
RestartSec=1
User=ec2-user
ExecStart=/usr/bin/docker-compose -f docker-compose.yml up

[Install]
WantedBy=multi-user.target

I created it in /etc/systemd/system folder

I then did:

sudo systemctl enable docker
sudo systemctl enable docker_boot

When I turn on the server, the only Docker images that are running are certbot/certbot and telethonkids/shinyproxy
Please find below the content of my docker-compose.yml file.
Do you see what is missing so that all images are up and running?

version: "3.5"
services:
  rstudio:
    environment:
      - USER=username
      - PASSWORD=password
    image: "rocker/tidyverse:latest"
    build:
     context: ./Docker_RStudio
     dockerfile: Dockerfile
    volumes:
      - /home/ec2-user/R_and_Jupyter_scripts:/home/maxence/R_and_Jupyter_scripts
    working_dir: /home/ec2-user/R_and_Jupyter_scripts
    container_name: rstudio
    ports:
      - 8787:8787

  jupyter:
    image: 'jupyter/datascience-notebook:latest'
    ports:
      - 8888:8888
    volumes:
     - /home/ec2-user/R_and_Jupyter_scripts:/home/joyvan/R_and_Jupyter_scripts
    working_dir: /home/joyvan/R_and_Jupyter_scripts
    container_name: jupyter

  shiny:
    image: "rocker/shiny:latest"
    build:
     context: ./Docker_Shiny
     dockerfile: Dockerfile
    container_name: shiny
    ports:
     - 3838:3838

  nginx:
    image: nginx:alpine
    container_name: nginx
    restart: on-failure
    networks:
     - net
    volumes:
     - ./nginx.conf:/etc/nginx/nginx.conf
     - ./data/certbot/conf:/etc/letsencrypt
     - ./data/certbot/www:/var/www/certbot
    ports:
     - 80:80
     - 443:443
    command: "/bin/sh -c 'while :; do sleep 6h & wait $${!}; nginx -s reload; done & nginx -g \"daemon off;\"'"
    depends_on:
     - shinyproxy

  certbot:
    image: certbot/certbot
    container_name: certbot
    restart: on-failure
    volumes:
     - ./data/certbot/conf:/etc/letsencrypt
     - ./data/certbot/www:/var/www/certbot
    entrypoint: "/bin/sh -c 'trap exit TERM; while :; do certbot renew; sleep 12h & wait $${!}; done;'"

  shinyproxy:
      image: telethonkids/shinyproxy
      container_name: shinyproxy
      restart: on-failure
      networks:
       - net
      volumes:
       - ./application.yml:/opt/shinyproxy/application.yml
       - /var/run/docker.sock:/var/run/docker.sock
      expose:
        - 8080

  cron:
   build:
     context: ./cron
     dockerfile: Dockerfile
   container_name: cron
   volumes:
     - ./Docker_Shiny/app:/home
   networks:
     - net

networks:
 net:
   name: net
ML_Enthousiast
  • 1,147
  • 1
  • 15
  • 39

2 Answers2

22

Using Amazon Linux 2 I tried to replicate the issue. Obviously, I don't have all the dependencies to run your exact docker-compose.yml, thus I used the docker-compose.yml from here for my verification. The file setups wordpress with mysql .

Steps I took were following (executed as ec2-user in home folder):

1. Install docker

sudo yum update -y  
sudo yum install -y docker
sudo systemctl enable docker
sudo systemctl start docker

2. Install docker-compose

sudo curl -L https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m) -o /usr/bin/docker-compose

sudo chmod +x /usr/bin/docker-compose

3. Create docker-compose.yml

mkdir myapp 

Create file ./myapp/docker-compose.yml:

version: '3.3'

services:
   db:
     image: mysql:5.7
     volumes:
       - db_data:/var/lib/mysql
     restart: always
     environment:
       MYSQL_ROOT_PASSWORD: somewordpress
       MYSQL_DATABASE: wordpress
       MYSQL_USER: wordpress
       MYSQL_PASSWORD: wordpress

   wordpress:
     depends_on:
       - db
     image: wordpress:latest
     ports:
       - "8000:80"
     restart: always
     environment:
       WORDPRESS_DB_HOST: db:3306
       WORDPRESS_DB_USER: wordpress
       WORDPRESS_DB_PASSWORD: wordpress
       WORDPRESS_DB_NAME: wordpress
volumes:
    db_data: {}

4. Create docker_boot.service

The file is different then yours, as there were few potential issues in your file:

  • not using absolute paths
  • ec2-user may have no permissions to run docker

Create file ./myapp/docker_boot.service:

[Unit]
Description=docker boot
After=docker.service

[Service]
Type=oneshot
RemainAfterExit=yes
WorkingDirectory=/home/ec2-user/myapp
ExecStart=/usr/bin/docker-compose -f /home/ec2-user/myapp/docker-compose.yml up -d --remove-orphans

[Install]
WantedBy=multi-user.target

5. Copy docker_boot.service to systemd

sudo cp -v ./myapp/docker_boot.service /etc/systemd/system

6. Enable and start docker_boot.service

sudo systemctl enable docker_boot.service
sudo systemctl start docker_boot.service

Note: First start may take some time, as it will pull all docker images required. Alternatively start docker-compose manually first to avoid this.

7. Check status of the docker_boot.service

sudo systemctl status docker_boot.service

8. Check if the wordpress is up

curl -L localhost:8000

9. Reboot

Check if the docker_boot.service is running after instance reboot by logging in into the instance and using sudo systemctl status docker_boot.service and/or curl -L localhost:8000.

Marcin
  • 215,873
  • 14
  • 235
  • 294
  • 1
    Amazing Marcin! I have adapted it and it works like a charm! Would you know what lines I should add to do as well `docker-compose down` when turning off the instance? Thanks again! – ML_Enthousiast Aug 21 '20 at 08:13
  • @ML_Enthousiast No problem. Glad it worked out :-) I think you could try `ExecStop=/usr/bin/docker-compose -f /home/ec2-user/myapp/docker-compose.yml down` in `[Service]`. But I haven't verified that, so I'm not certain. – Marcin Aug 21 '20 at 08:19
  • 2
    You could just add "restart: always" in your docker-compose file. Then you won't need to create any docker_boot.service file. If the docker machine turns on the container will restart automatically. – Muhtadi Akif Apr 23 '21 at 06:47
4

To have a service launch at launch you would run the following command sudo systemctl enable docker.

For having it then launch your docker compose up -d command you'd need to create a new service for your specific action, and then enable it with the contents similar to the below.

[Unit]
After=docker.service
Description=Docker compose

[Service]
ExecStart=docker-compose up -d

[Install]
WantedBy=multi-user.target

More information for this is available in this post.

Chris Williams
  • 32,215
  • 4
  • 30
  • 68