I've used the following service definition file to set up a systemd service.
[Unit]
Description=MappingService
After=docker.service
Requires=docker.service
[Service]
TimeoutStartSec=3000
WorkingDirectory=/home/oren/MappingService
ExecStartPre=-/usr/bin/sudo /home/oren/MappingService/deploy.sh /home/oren/MappingService/eb-mapping-service.tgz
ExecStart=/usr/bin/sudo /home/oren/MappingService/ebms_run.sh
Type=simple
[Install]
WantedBy=multi-user.target
That service's purpose is to launch a specific docker container. The operation appears to be successful as the docker appears in:
docker container ls
it is listening on port 9090 and I succeeded in verifying that port is open with nmap.
but when I check the service status on systemctl, (systemctl status mappingservice.service)
I get inactive(dead) as appears below.
● mappingservice.service - MappingService Loaded: loaded
(/etc/systemd/system/mappingservice.service; enabled; vendor preset:
enabled) Active: inactive (dead) since Thu 2019-02-14 14:54:20 IST;
20min ago Process: 1784 ExecStart=/usr/bin/sudo
/home/oren/MappingService/ebms_run.sh (code=exited, status=0/SUCCESS)
Process: 1323 ExecStartPre=/usr/bin/sudo
/home/oren/MappingService/deploy.sh
/home/oren/MappingService/eb-mapping-service.tgz (code=exited,
status=0/SUCCESS)
I've searched on here for clues and I only found references to systemd usage of the actual docker service and not a specific container like I'm trying to do here.
Contents of ebms_run.sh:
#!/bin/bash -x
source defs.sh
DOCKER_PARAMS="-v /dev/log:/dev/log -d --log-driver=journald --add-host=<server1-alias1>:172.17.0.1 --add-host=<server1-alias2>:172.17.0.1 --network=bridge -p 9090:9090 --name ${DOCKER_CONTAINER_NAME}"
docker rm -f ${DOCKER_CONTAINER_NAME}
docker run ${DOCKER_PARAMS} ${DOCKER_IMAGE_NAME} /bin/bash -c "cd /build/MappingService; ./start_multiple_clients_mapping_service.sh
The script start_multiple_clients_mapping_service.sh is running inside the docker container and is actually continuous. It will not die until the docker dies.
Question:
How should I configure my systemd service to manage the docker container?
Related
I have this small flask application that is running on gunicorn and I am trying to run it as a systemd service. I have created a unit file in my local directory in ~/.config/my-user/user/gunicorn.service
[Unit]
Description=Gunicorn app
After=network.target
[Service]
User=my-user
Group=www-data
WorkingDirectory=/home/my-user/repo
ExecStart=/home/my-user/repo/venv/bin/gunicorn -b 0.0.0.0:8000 app:app
[Install]
WantedBy=multi-user.target
I get this error when trying to run sudo systemctl --user start gunicorn. I am running on amazon linux 1:
Failed to get D-Bus connection: Connection refused
what am i missing here?
I have an interesting problem that I have a reproducer for. Using a container to compartmentalize this system and make it reproducible, I can have it run successfully on my powerful laptop, but when running on a slow raspberry Pi it fails.
::::::::::::::
A.service
::::::::::::::
[Unit]
Description=Service A
After=B.service
BindsTo=B.service
[Service]
Type=simple
Restart=always
RestartSec=1
ExecStartPre=/bin/sleep 1
ExecStart=/bin/sleep 100
ExecStartPost=/bin/sleep 1
TimeoutStartSec=10s
[Install]
WantedBy=multi-user.target
::::::::::::::
B.service
::::::::::::::
[Unit]
Description=Service A
After=C.service
BindsTo=C.service
[Service]
Type=simple
Restart=always
RestartSec=1
ExecStartPre=/bin/sleep 1
ExecStart=/bin/sleep 100
ExecStartPost=/bin/sleep 1
TimeoutStartSec=10s
[Install]
WantedBy=multi-user.target
::::::::::::::
C.service
::::::::::::::
[Unit]
Description=Service A
[Service]
Type=simple
Restart=always
RestartSec=1
ExecStartPre=/bin/sleep 1
ExecStart=/bin/sleep 100
ExecStartPost=/bin/sleep 1
TimeoutStartSec=10s
[Install]
WantedBy=multi-user.target
::::::::::::::
Dockerfile
::::::::::::::
FROM ubuntu:18.04
RUN DEBIAN_FRONTEND=noninteractive apt update && apt install -y systemd init socat
COPY *.service /etc/systemd/system/
#RUN systemctl enable A.service
ENTRYPOINT ["/sbin/init"]
::::::::::::::
run.sh
::::::::::::::
docker build -t service .
docker stop -t 0 service && docker rm service
docker run -d --name service --privileged --cap-add SYS_ADMIN service
#docker run -d --cpus="0.3" --name service --privileged --cap-add SYS_ADMIN service
sleep 3
docker exec -it service service A start
sleep 1
docker exec -it service service A status
docker exec -it service service B status
docker exec -it service service C status
What the intent here is that there are 3 services: A, B, and C. The dependency is as follows: A->B->C. When starting service A, B should be started which then in turn starts C. The services are dummy services in this case and I've tried adding delays pre and post service, but the problem persists.
On my powerful laptop, I can somewhat reproduce the issue by adding "--cpus=0.3" to the 'docker run' line.
Any ideas on what could be the culprit?
I have discovered that service has an interesting "feature":
# avoid deadlocks during bootup and shutdown from units/hooks
# which call "invoke-rc.d service reload" and similar, since
# the synchronous wait plus systemd's normal behaviour of
# transactionally processing all dependencies first easily
# causes dependency loops
if ! systemctl --quiet is-active multi-user.target; then
sctl_args="--job-mode=ignore-dependencies"
fi
Obviously, if systemctl is launched with --job-mode=ignore-dependencies, it is less likely to work :-).
As expected, the following sequence works:
docker run -d --name service --privileged --cap-add SYS_ADMIN service
docker exec -ti service systemctl start multi-user.target
docker exec -it service service A start
Obviously, the best option is to replace service A start by systemctl start A. BTW, service is specific to Ubuntu while systemctl is common to nearly any Linux distribution.
I think that any service manually started in a docker container is impacted by this issue.
However, I still don't explain why it works on your powerful laptop.
I have a Linux Virtual Machine on Azure. On this machine I installed Docker. At the startup, I want to run a Docker container. For that, I created a startup_script.sh in the tmp folder with this content
sudo docker run -d -p 8787:8787 -e USER=rstudio
-e PASSWORD=mypassword myacr.azurecr.io/mycontainer
then I run this command
chmod u+x /tmp/startup_script.sh
Then, under etc/systemd/system I created a service
[Unit]
Description=Run script at startup after network becomes reachable
After=default.target
[Service]
Type=simple
RemainAfterExit=yes
ExecStart=/tmp/startup_script.sh
TimeoutStartSec=0
[Install]
WantedBy=default.target
Then, run
systemctl daemon-reload
systemctl enable run-at-startup.service
When I restart the machine, the Docker container is not running.
Docker recommends that you use its restart policies, and avoid using process managers like systemctl to start containers (https://docs.docker.com/config/containers/start-containers-automatically/).
First, you need to make sure that Docker Daemon (i.e. Docker service) start on boot.
On Debian and Ubuntu, the Docker service is configured to start on boot by default. To automatically start Docker and Containerd on boot for other distros, use the commands below:
sudo systemctl enable docker.service
sudo systemctl enable containerd.service
If you're on Windows, make sure that you ticked Start Docker Desktop when you log in in Docker Desktop settings.
Then, for each container you want to start on boot, you need to use the --restart flag when running the container, e.g.:
sudo docker run --restart always -d -p 8787:8787 -e USER=rstudio
-e PASSWORD=mypassword myacr.azurecr.io/mycontainer
When I run an ASP.NET Core website from Putty in Ubuntu 20.04:
/usr/bin/dotnet /root/dev/myWebApp/myWebApp/myWebApp.dll
OR
dotnet /root/dev/myWebApp/myWebApp/myWebApp.dll
It runs website fine on browser: localhost:5000 or https://localhost:5001
But when I try to start it as a service "website.service" using:
sudo nano /etc/systemd/system/website.service
And write file:
[Unit]
Description=Example .NET Web API App running on Ubuntu
[Service]
WorkingDirectory=/root/dev/myWebApp/myWebApp
ExecStart=/usr/bin/dotnet /root/dev/myWebApp/myWebApp/myWebApp.dll
Restart=always
# Restart service after 10 seconds if the dotnet service crashes:
RestartSec=10
KillSignal=SIGINT
SyslogIdentifier=dotnet-example
User=www-data
Environment=ASPNETCORE_ENVIRONMENT=Production
Environment=DOTNET_PRINT_TELEMETRY_MESSAGE=false
[Install]
WantedBy=multi-user.target
And then:
sudo systemctl enable website.service
sudo systemctl daemon-reload
sudo systemctl start website.service
The service starts but localhost:5000 or https://localhost:5001 does not open
and
sudo systemctl status website.service
Gives:
website.service - Example .NET Web API App running on Ubuntu
Loaded: loaded (/etc/systemd/system/website.service; enabled; vendor prese>
Active: activating (auto-restart) (Result: exit-code) since Sat 2021-08-21>
Process: 2421 ExecStart=/usr/bin/dotnet /root/dev/myWebApp/myWebApp/myWebAp>
Main PID: 2421 (code=exited, status=200/CHDIR)
Note:
Steps to recreate ASP.NET core environment and project:
Install dotnet core 5.0
wget https://packages.microsoft.com/config/ubuntu/20.04/packages-microsoft-prod.deb -O packages-microsoft-prod.deb
sudo dpkg -i packages-microsoft-prod.deb
sudo apt update
sudo apt install apt-transport-https
sudo apt update
sudo apt install dotnet-sdk-5.0
Create, build and publish asp.net core project
mkdir dev
cd dev
dotnet --info
dotnet new webApp -o myWebApp //Create a basic web application that should listen on 5000 port
cd myWebApp
dotnet build //Builds the project
dotnet publish -c release -o myWebApp //Publishes the project as a myWebApp.dll on /root/dev/myWebApp/myWebApp/myWebApp.dll path, it should run in "website.service" file
I followed this tutorial: https://www.youtube.com/watch?v=M3G4bNRZTDo and partially from time: 5:44: https://www.youtube.com/watch?v=Sw6USmvt60s
I found the answer, the service file does not run dll from /root/dev folder, it runs file fine from /var/www folder.
I am running CoreOS Stable 776.4.0.
I want to keep a container running all the time. But I cannot get it to work. When I expect the container to restart when it is killed. But it does not. I got it working before. But I don't remember how I did it.
Please help me!
I kill it by docker stop proxy
Restart=always will continuously stop and start the container.
This is my systemd unit file.
[Unit]
Description=nginx reverse proxy
After=docker.service
Requires=docker.service
[Service]
TimeoutStartSec=0
Restart=on-failure
ExecStartPre=-/usr/bin/docker stop proxy
ExecStartPre=-/usr/bin/docker rm proxy
ExecStart=/usr/bin/docker run -d --name proxy -p 80:80 -v
/var/run/docker.sock:/tmp/docker.sock:ro zhex900/nginx-proxy
[Install]
WantedBy=multi-user.target
Your immediate problem is this:
ExecStart=/usr/bin/docker run -d --name proxy -p 80:80 -v
/var/run/docker.sock:/tmp/docker.sock:ro zhex900/nginx-proxy
You are passing the -d option to the docker client, which means "start the container in the background and return immediately". Because the client exits, systemd interprets this as a failure and will attempt to restart the service.
The simplest solution is to remove the -d from the command line.
Another option is to not use systemd, and to simply start the container with docker run --restart=always ..., which will cause Docker to ensure that the container is running, even after a reboot.
Sorry, I asked a stupid question. The problem was I was running the container as a daemon. Remove -d solved the problem.
ExecStart=/usr/bin/docker run --name proxy -p 80:80 \
-v /var/run/docker.sock:/tmp/docker.sock:ro zhex900/nginx-proxy