gdraheim / docker-systemctl-replacement

docker systemctl replacement - allows to deploy to systemd-controlled containers without starting an actual systemd daemon (e.g. centos7, ubuntu16)
European Union Public License 1.2
1.39k stars 399 forks source link

Starting a service during image build / docker file, hangs #156

Closed punowo closed 1 year ago

punowo commented 1 year ago

Hello. I'm trying to build an image that I can use as a development environment. I'm on WSL. The idea would be to just docker compose up -d, have the source code in WSL and then build and run the software. Currently calling systemctl start just gets stuck.

The dockerfile is:

FROM  --platform=linux/amd64 almalinux:9-minimal
ENV container docker
USER root:root

RUN microdnf -y update \
    && microdnf -y install --nodocs python3 \
    && microdnf -y clean all \
    && rm -rf /var/cache/yum 

ADD https://raw.githubusercontent.com/gdraheim/docker-systemctl-replacement/master/files/docker/systemctl3.py /usr/local/sbin/systemctl
RUN chmod +x /usr/local/sbin/systemctl

RUN echo -e "[mongodb-org-6.0]\nname=MongoDB Repository \nbaseurl=https://repo.mongodb.org/yum/redhat/9/mongodb-org/6.0/x86_64/ \ngpgcheck=1 \nenabled=1 \ngpgkey=https://www.mongodb.org/static/pgp/server-6.0.asc" > /etc/yum.repos.d/mongodb-org-6.0.repo

RUN microdnf -y update \
    && microdnf -y install --nodocs nano vim-minimal mongodb-org nginx procps-ng gcc python3 tar which \
    && microdnf -y clean all \
    && rm -rf /var/cache/yum 
RUN ln -sf /usr/bin/python3 /usr/bin/python

RUN curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.3/install.sh | bash

RUN systemctl start nginx -vvv
RUN systemctl start mongod &

RUN mkdir -p /data/db
RUN chmod -R 777 /data/db
VOLUME [ "/data/db" ]
EXPOSE 27017

RUN . ~/.nvm/nvm.sh && nvm install --lts

EXPOSE 80

COPY docker-entrypoint.sh /usr/local/bin/
RUN ["chmod", "+x", "/usr/local/bin/docker-entrypoint.sh"]
ENTRYPOINT ["docker-entrypoint.sh"

docker-compose.yml

services:
  application:
    build: .
    privileged: true
    container_name: application
    ports:
      - 27017:27017
      - 80:80
    volumes:
      - /sys/fs/cgroup:/sys/fs/cgroup:ro
      - /mnt/application/data/db:/data/db:rw

docker-entrypoint.sh

#!/usr/bin/env bash

tail -f /dev/null

Here are some screenshots. Screenshot_1 Screenshot_2

gdraheim commented 1 year ago

Every RUN creates a seperate container, so you can not have background process that still exist in the next RUN.

Please check the examples how to do it.

https://github.com/gdraheim/docker-systemctl-images/blob/master/centos8-lamp-stack.dockerfile

punowo commented 1 year ago

Thanks. I'll look into it.

punowo commented 1 year ago

Is there a way I can do this without having CMD /usr/bin/systemctl as entrypoint ? Similar to how I'm trying to do it ?

gdraheim commented 1 year ago

systemctl as the entrypoint does basically execute all ExecStart in enabled x.service files. If you want to run the application parts manually then go ahead with your own wrapper. However everything you do in a docker-entrypoint script can also be encoded in the x.service format.

gdraheim commented 1 year ago

Oh, and dont forget that systemctl on PID-1 works as a zombie reaper and it can return stop services for a clean shutdown which is what most docker-entrypoint scripts are missing.

punowo commented 1 year ago

I understand everything you just said except this little part, If you want to run the application parts manually then go ahead with your own wrapper.. Could you please expand a little on it ? Are you referring to a .service file ?

gdraheim commented 1 year ago

The container should have some application running if you want to have it as server. In general the docker-entrypoint does it. Probably you can override that with a docker-compose or statefulset definition but that's all up to you. Instead of defining the start-command outside you can just as well encode them in an ExecStart in some x.service.