unit icon indicating copy to clipboard operation
unit copied to clipboard

Listen on unix domain socket (like uwsgi)

Open sandeep048 opened this issue 7 years ago • 11 comments

Can we use unix domain sockets for the unit listeners and use them in nginx proxy_pass? This would radically simplify deployment of multiple webapps.

sandeep048 avatar Nov 09 '17 09:11 sandeep048

Yes, unix domain sockets can be used in the same format as in nginx: "unix:/path/to/socket". The only issue now is the sockets are not deleted on unit exit or reconfiguration so you have to delete them manually. However we will fix this bug soon.

igorsysoev avatar Nov 09 '17 12:11 igorsysoev

@sandeep048 We will keep this issue open until we add the remaining features related to socket handling.

Just to clarify further, the following would be a minimal socket config:

{
	"listeners": {
		"unix:/tmp/app.sock": {
			"application": "myapp"
		}
	},

	"applications": {
		"myapp": {
                        ... app settings here ...
		}
	}
}

nshadrin avatar Apr 24 '18 19:04 nshadrin

Will this functionality be implemented?

user0386 avatar Oct 25 '18 06:10 user0386

How can one address a socket listener via the API? The equivalent of <host>/config/listeners/<ip>:<port>/,

<host>/config/listeners/unix:/path/to/socket/

does not seem to work. Also, any update on when the automatic deletion of sockets will be implemented?

lcts avatar Nov 28 '18 09:11 lcts

@lcts Addressing of such socket name isn't something supported right now. There's a plan to make it possible via URI-escaping, e.g.: /config/listeners/unix:%2Fpath%2Fto%2Fsocket/.

Sorry, still no updates on automatic deletion. Frankly speaking, the full support of listening on unix domain sockets isn't our priority, since Unit is not meant to be put behind local reverse proxy.

VBart avatar Nov 29 '18 13:11 VBart

Does the commit https://github.com/nginx/unit/commit/fd6a6a5514c420dae2b393f62fee65f87758dec9 fixed the problem of socket deletion?

UPDATE: The commit does not solve the problem, I needed to remove the socket in startup script to get restart working.

Please, fix this 3 years old problem.

Peter2121 avatar May 05 '21 16:05 Peter2121

@igorsysoev

fyi re:

Yes, unix domain sockets can be used in the same format as in nginx: "unix:/path/to/socket". The only issue now is the sockets are not deleted on unit exit or reconfiguration so you have to delete them manually. However we will fix this bug soon.

with

unitd --version
  unit version: 1.24.0
  configured as ./configure --libdir=/usr/lib64 --prefix=/usr --state=/var/lib/unit --control=unix:/run/unit/control.sock --pid=/run/unit/unit.pid --log=/var/log/unit/unit.log --tmp=/var/tmp --user=unit --group=unit --openssl --cc-opt='-O2 -fexceptions -g -grecord-gcc-switches -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -fstack-protector-strong -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -m64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection' --tests --modules=/usr/lib64/unit/modules

exec of

rm -f /run/unit/php.app.sock
ls -al /run/unit/php.app.sock
	ls: cannot access '/run/unit/php.app.sock': No such file or directory

curl --unix-socket /run/unit/unit.sock -X PUT --data-binary '{
	"listeners": {
		"unix:/run/unit/php.app.sock": {
			"pass": "applications/php"
		}
	},
	"applications": {
		"php": {
			"type": "php",
			"root": "/www",
		}
	}
}' http://localhost/config

returns

{
        "error": "Failed to apply new configuration."
}

change

-		"unix:/run/unit/php.app.sock": {
+		"127.0.0.1:12345": {

exec of

curl --unix-socket /run/unit/unit.sock -X PUT --data-binary '{
	"listeners": {
		"127.0.0.1:12345": {
			"pass": "applications/php"
		}
	},
	"applications": {
		"php": {
			"type": "php",
			"root": "/www",
		}
	}
}' http://localhost/config

returns

	{
		"success": "Reconfiguration done."
	}

pgnd avatar Jun 09 '21 13:06 pgnd

@pgnd Make sure you are using PUT method (as you did for 127.0.0.1:12345 listener) when upload complete configuration.

mar0x avatar Jun 10 '21 08:06 mar0x

@mar0x

yep, sry; that was copy-n-paste of the wrong notes. :-/

with PUT, instead of post, it still fails, but with

        "error": "Failed to apply new configuration."

rather than

	"error": "Method isn't allowed."

pgnd avatar Jun 10 '21 10:06 pgnd

@pgnd Please check the unit.log for the reason of the configuration apply failure. It can be "Address already in use" if socket file already exists or something else.

mar0x avatar Jun 10 '21 12:06 mar0x

@mar0x

you're correct. the socket's still not getting deleted on unitd stop, and prevents the exec:

systemctl stop unit
rm -f /usr/local/etc/nginx-unit/state/conf.json
rm -f /run/unit/*unit*
systemctl start unit

ps ax | grep unit
	46708 ?        Ss     0:00 unit: main v1.24.0 [/usr/sbin/unitd --control unix:/run/unit/unit.sock --pid /run/unit/unit.pid --log /var/log/nginx/unit.log --state /usr/local/etc/nginx-unit/state --user wwwrun --group www --no-daemon]
	46716 ?        S      0:00 unit: controller
	46717 ?        S      0:00 unit: router

tree /usr/local/etc/nginx-unit/state/
	/usr/local/etc/nginx-unit/state/
	└── certs

	1 directory, 0 files

ls -al /run/unit/*unit*
	-rw-r--r-- 1 wwwrun www 6 Jun 10 08:39 /run/unit/unit.pid
	srw------- 1 wwwrun www 0 Jun 10 08:39 /run/unit/unit.sock=

cat /work/php.config.json
	{
		"listeners": {
			"unix:/run/unit/php.app.sock": {
				"pass": "applications/php"
			}
		},
		"applications": {
			"php": {
				"type": "php",
				"root": "/www",
			}
		}
	}

curl --unix-socket /run/unit/unit.sock -X PUT \
 --data-binary @/work/php.config.json \
http://localhost/config

	{
			"success": "Reconfiguration done."
	}

tail -f /var/log/nginx/unit.log
	2021/06/10 08:45:14 [info] 47131#47131 "php" application started

tree /usr/local/etc/nginx-unit/state/
	/usr/local/etc/nginx-unit/state/
	├── certs
	└── conf.json

	1 directory, 1 file

ls -al /run/unit/*unit*
	srw-rw-rw- 1 wwwrun www 0 Jun 10 08:45 /run/unit/php.app.sock=
	-rw-r--r-- 1 wwwrun www 6 Jun 10 08:39 /run/unit/unit.pid
	srw------- 1 wwwrun www 0 Jun 10 08:39 /run/unit/unit.sock=

systemctl stop unit
ls -al /run/unit/*unit*
	srw-rw-rw- 1 wwwrun www 0 Jun 10 08:45 /run/unit/php.app.sock=

systemctl start unit
ls -al /run/unit/*unit*
	srw-rw-rw- 1 wwwrun www 0 Jun 10 08:45 /run/unit/php.app.sock=
	-rw-r--r-- 1 wwwrun www 6 Jun 10 08:47 /run/unit/unit.pid
	srw------- 1 wwwrun www 0 Jun 10 08:47 /run/unit/unit.sock=

curl --unix-socket /run/unit/unit.sock -X PUT \
 --data-binary @/work/php.config.json \
http://localhost/config

	{
			"error": "Failed to apply new configuration."
	}

tail -f /var/log/nginx/unit.log

	2021/06/10 08:48:19 [alert] 47299#47299 bind(\"unix:/run/unit/php.app.sock\") failed (98: Address already in use)
	2021/06/10 08:48:19 [alert] 47306#47306 failed to apply new conf

pgnd avatar Jun 10 '21 12:06 pgnd