Spring 使用 init.d 以 root 而不是用户身份启动可执行 jar
Spring boot executable jar with init.d launching as root instead of user
求助!
我正在使用 SpringBoot 1.3.6 和 Gradle 的内置启动脚本。哦,还有用于压缩内容的 distZip 任务。
不久前的某一时刻,这一切都运行良好......然后我做了——我不知道是什么——把它搞砸了。
我已经在我的 raspberry Pi 上安装了软件包(基本上是解压 Zip),并检查了所有权和权限。一切都归我想 运行 应用程序的用户所有(用户 "appservice" 组 "pi")并确认文件的权限是——如果有的话,过于宽松(755 myapp/bin/myapp 脚本和几乎所有其他内容)。
我在 /etc/init.d 中放置了一个指向 ~appservice/myapp/bin/myapp 的符号链接并且我已经 运行 update-rc.d myapp 默认获取它进入系统。请注意,符号链接本身属于 root/root,但我相信它应该属于,不是吗?
我看到两个问题,我认为它们是相互关联的。
首先,无论我如何启动脚本(使用 init.d 启动或使用 "sudo service myapp start" 手动启动),它在 运行 中显示为 root(具体来说,应用程序的路径正在尝试使用访问文件 /root/myapp/files 而不是 /home/appservice/myapp/files).
其次,应用程序会崩溃...具体来说,我收到系统日志消息 "myapp.service start operation timed out. Terminating.",然后是应用程序有序关闭的消息。哦,还有相关的...如果我使用 "sudo service myapp start" 启动,命令永远不会 returns。哪个是新的...
第三,应用程序日志输出到 /var/log/syslog 而不是 /var/log/myapp.log,这似乎与 Spring 引导文档所说的相反。
我正在为此部署进行最终回归测试,并且(著名的遗言)我最近没有更改任何内容...:) 不,真的,与分发相关的最新更改是添加 src/main/dist 目录,之后它就可以工作了(以正确的用户身份在启动时启动)。
我会 post 启动脚本,但 AFAIK 它是 Spring 当您使用 springBoot { executable = true } 任务时启动时提供的默认脚本。
这是我的完整 build.gradle 文件...我没有发现任何问题,但也许您会看到。
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:1.3.6.RELEASE")
}
}
apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'idea'
apply plugin: 'spring-boot'
apply plugin: 'application'
apply from: 'gradle/gradle/helpers.gradle'
mainClassName = 'app.Application'
if (!hasProperty('mainClass')) {
ext.mainClass = 'app.Application'
}
springBoot {
executable = true
}
repositories {
mavenCentral()
}
sourceSets {
main {
java { srcDir 'src/main/java' }
resources { srcDir '/src/main/resources' }
}
test {
java { srcDir 'src/test/java' }
resources { srcDir 'src/test/resources' }
}
}
project.ext {
applicationVersion = "0.1.5-alpha"
applicationRelease = isApplicationRelease()
applicationDate = new Date()
applicationRevision = getRevision()
applicationVersionSnapshot = (!applicationRelease) ? "+SNAPSHOT.${asUTC(applicationDate, 'yyMMddHHmm')}.git${applicationRevision}" : ""
applicationVersionFull = "${applicationVersion}${applicationVersionSnapshot}"
}
jar {
baseName = 'myapp'
version = '0.9.0'
}
sourceCompatibility = 1.8
targetCompatibility = 1.8
dependencies {
compile group: 'com.sun.mail', name: 'javax.mail', version: '1.5.2'
compile group: 'org.apache.httpcomponents', name: 'httpclient', version: '4.3.6'
compile group: 'commons-cli', name:'commons-cli', version: '1.3.1'
compile group: 'org.json', name:'json', version: '20140107'
compile "commons-codec:commons-codec:1.10"
compile("org.springframework.boot:spring-boot-starter-hateoas")
compile("org.springframework.boot:spring-boot-starter-web")
compile("org.springframework.boot:spring-boot-starter-thymeleaf")
compile("org.springframework.boot:spring-boot-starter-mail")
compile("org.springframework.boot:spring-boot-starter-security")
compile("org.springframework:spring-web")
compile("org.springframework:spring-messaging")
compile("joda-time:joda-time:2.2")
compile("com.fasterxml.jackson.core:jackson-databind")
compile("com.googlecode.json-simple:json-simple")
compile("org.jdom:jdom:2.0.0")
compile("org.hibernate:hibernate-validator")
compile("org.apache.tomcat.embed:tomcat-embed-el")
compile("org.apache.commons:commons-io:1.3.2")
compile("org.kamranzafar:jtar:2.3")
compile("org.thymeleaf.extras:thymeleaf-extras-springsecurity4")
compile("com.jcraft:jsch:0.1.53")
compile("javax.jmdns:jmdns:3.4.1")
testCompile("org.springframework.boot:spring-boot-starter-test")
}
task wrapper(type: Wrapper) {
gradleVersion = '2.14'
}
我会向 运行 推荐并使用 systemd
管理您的应用程序。
这使得运行特定用户下的应用程序变得非常容易。
为此,请继续以下操作:
首先,使用以下内容创建服务定义文件/etc/systemd/system/myapp.service
:
[Unit]
Description=My App
[Service]
User=nobody
# The configuration file application.properties should be here:
WorkingDirectory=/home/appservice/myapp/files
ExecStart=/usr/bin/java -Xmx256m -jar myapp.jar
SuccessExitStatus=143
[Install]
WantedBy=multi-user.target
然后,通知systemd
新的服务文件:
systemctl daemon-reload
并启用它,所以它 运行s 在启动时:
systemctl enable myapp.service
最后您可以使用以下命令start/stop您的新服务:
systemctl start myapp
systemctl stop myapp
求助!
我正在使用 SpringBoot 1.3.6 和 Gradle 的内置启动脚本。哦,还有用于压缩内容的 distZip 任务。
不久前的某一时刻,这一切都运行良好......然后我做了——我不知道是什么——把它搞砸了。
我已经在我的 raspberry Pi 上安装了软件包(基本上是解压 Zip),并检查了所有权和权限。一切都归我想 运行 应用程序的用户所有(用户 "appservice" 组 "pi")并确认文件的权限是——如果有的话,过于宽松(755 myapp/bin/myapp 脚本和几乎所有其他内容)。
我在 /etc/init.d 中放置了一个指向 ~appservice/myapp/bin/myapp 的符号链接并且我已经 运行 update-rc.d myapp 默认获取它进入系统。请注意,符号链接本身属于 root/root,但我相信它应该属于,不是吗?
我看到两个问题,我认为它们是相互关联的。
首先,无论我如何启动脚本(使用 init.d 启动或使用 "sudo service myapp start" 手动启动),它在 运行 中显示为 root(具体来说,应用程序的路径正在尝试使用访问文件 /root/myapp/files 而不是 /home/appservice/myapp/files).
其次,应用程序会崩溃...具体来说,我收到系统日志消息 "myapp.service start operation timed out. Terminating.",然后是应用程序有序关闭的消息。哦,还有相关的...如果我使用 "sudo service myapp start" 启动,命令永远不会 returns。哪个是新的...
第三,应用程序日志输出到 /var/log/syslog 而不是 /var/log/myapp.log,这似乎与 Spring 引导文档所说的相反。
我正在为此部署进行最终回归测试,并且(著名的遗言)我最近没有更改任何内容...:) 不,真的,与分发相关的最新更改是添加 src/main/dist 目录,之后它就可以工作了(以正确的用户身份在启动时启动)。
我会 post 启动脚本,但 AFAIK 它是 Spring 当您使用 springBoot { executable = true } 任务时启动时提供的默认脚本。
这是我的完整 build.gradle 文件...我没有发现任何问题,但也许您会看到。
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:1.3.6.RELEASE")
}
}
apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'idea'
apply plugin: 'spring-boot'
apply plugin: 'application'
apply from: 'gradle/gradle/helpers.gradle'
mainClassName = 'app.Application'
if (!hasProperty('mainClass')) {
ext.mainClass = 'app.Application'
}
springBoot {
executable = true
}
repositories {
mavenCentral()
}
sourceSets {
main {
java { srcDir 'src/main/java' }
resources { srcDir '/src/main/resources' }
}
test {
java { srcDir 'src/test/java' }
resources { srcDir 'src/test/resources' }
}
}
project.ext {
applicationVersion = "0.1.5-alpha"
applicationRelease = isApplicationRelease()
applicationDate = new Date()
applicationRevision = getRevision()
applicationVersionSnapshot = (!applicationRelease) ? "+SNAPSHOT.${asUTC(applicationDate, 'yyMMddHHmm')}.git${applicationRevision}" : ""
applicationVersionFull = "${applicationVersion}${applicationVersionSnapshot}"
}
jar {
baseName = 'myapp'
version = '0.9.0'
}
sourceCompatibility = 1.8
targetCompatibility = 1.8
dependencies {
compile group: 'com.sun.mail', name: 'javax.mail', version: '1.5.2'
compile group: 'org.apache.httpcomponents', name: 'httpclient', version: '4.3.6'
compile group: 'commons-cli', name:'commons-cli', version: '1.3.1'
compile group: 'org.json', name:'json', version: '20140107'
compile "commons-codec:commons-codec:1.10"
compile("org.springframework.boot:spring-boot-starter-hateoas")
compile("org.springframework.boot:spring-boot-starter-web")
compile("org.springframework.boot:spring-boot-starter-thymeleaf")
compile("org.springframework.boot:spring-boot-starter-mail")
compile("org.springframework.boot:spring-boot-starter-security")
compile("org.springframework:spring-web")
compile("org.springframework:spring-messaging")
compile("joda-time:joda-time:2.2")
compile("com.fasterxml.jackson.core:jackson-databind")
compile("com.googlecode.json-simple:json-simple")
compile("org.jdom:jdom:2.0.0")
compile("org.hibernate:hibernate-validator")
compile("org.apache.tomcat.embed:tomcat-embed-el")
compile("org.apache.commons:commons-io:1.3.2")
compile("org.kamranzafar:jtar:2.3")
compile("org.thymeleaf.extras:thymeleaf-extras-springsecurity4")
compile("com.jcraft:jsch:0.1.53")
compile("javax.jmdns:jmdns:3.4.1")
testCompile("org.springframework.boot:spring-boot-starter-test")
}
task wrapper(type: Wrapper) {
gradleVersion = '2.14'
}
我会向 运行 推荐并使用 systemd
管理您的应用程序。
这使得运行特定用户下的应用程序变得非常容易。
为此,请继续以下操作:
首先,使用以下内容创建服务定义文件/etc/systemd/system/myapp.service
:
[Unit]
Description=My App
[Service]
User=nobody
# The configuration file application.properties should be here:
WorkingDirectory=/home/appservice/myapp/files
ExecStart=/usr/bin/java -Xmx256m -jar myapp.jar
SuccessExitStatus=143
[Install]
WantedBy=multi-user.target
然后,通知systemd
新的服务文件:
systemctl daemon-reload
并启用它,所以它 运行s 在启动时:
systemctl enable myapp.service
最后您可以使用以下命令start/stop您的新服务:
systemctl start myapp
systemctl stop myapp