spring-boot-nginx代理-docker-compose部署
在本地测试,使用docker部署不用在意环境
java测试项目:
- web框架:spring boot 框架
- 项目管理:maven
- 数据库:redis + postgres + mongo
- 部署相关:nginx + docker-compose
项目目录:
项目结构如图,废话不多说,上代码
一、本地web代码测试和打包jar
1、首先需要本地代码能跑起来
2、打包成jar,(具体打包查看spring官网:http://spring.io/guides/gs/rest-service/),打包后,在target目录下生成一些文件夹和文件,重要的看项目结构图红框圈中的文件,就是它:gs-spring-boot-0.1.0.jar
(命令打包:mvn clean package -DskipTests )
二、使用jar包制作docker镜像
使用docker把jar文件做成镜像,使用Dockerfile方式
Dockerfile内容:
FROM java:
ADD ./target/gs-spring-boot-0.1..jar app.jar
RUN bash -c 'touch /app.jar'
ENTRYPOINT ["java","-jar","/app.jar"]
注意:Dockerfile文件放哪随便(不要放到target下),路径不一样,需要更改 ADD指令后面的路径地址,确保能通过相对路径找到并添加jar包
进入到Dockerfile所在目录,执行docker build 命令,制作镜像:
docker build -t java_compose .
点".",代表使用当前路径下的Dockerfile文件,可以不进入Dockerfile所在目录执行build命令,需要把 点“.” 换成绝对路径或相对路径,找到Dockerfile文件
然后可以查看镜像:
docker images
redis、postgres、mongo、nginx镜像都是从官方拉取的镜像,不多少了
三、docker-compose.yml文件
docker-compose.yml:
version: ''
services:
nginxxx:
image: nginx:latest
container_name: nginxxx
restart: unless-stopped
ports:
- :
volumes:
- ./nginx.conf:/etc/nginx/conf.d/default.conf //docker容器启动停止,内部配置消失,所以挂在外面的配置文件,不会丢失 redisxx:
image: redis:latest
container_name: redisxx
restart: unless-stopped
env_file: .env
ports:
- :
# volumes:
# - redis-data:/bitnami/redis postgresxx:
image: postgres:latest
container_name: postgresxx
restart: unless-stopped
env_file: .env
command: postgres -c 'max_connections=200'
ports:
- :
environment:
- POSTGRES_USER=testdb //创建用户名
- POSTGRES_PASSWORD=testdb //创建密码 有这两个参数,可以不用再创建数据库,会默认创建和用户名一样的数据库,如果想创建其他的数据库名字,可以再加参数POSTGRES_DB=your_db_name
# volumes:
# - pg-data:/var/lib/postgresql/data mymongoxx:
image: mongo:latest
container_name: mymongoxx
restart: unless-stopped
env_file: .env
ports:
- :
environment:
- MONGO_INITDB_ROOT_USERNAME=testdb //创建root用户名
- MONGO_INITDB_ROOT_PASSWORD=testdb //创建root用户密码 注意:创建用户名和密码后,会开启auth认证,xxxx_application.properties需要配置认证数据库配置信息spring.data.mongodb.authentication-database=admin
- MONGO_INITDB_DATABASE=testdb //创建集合(数据库)
# volumes:
#- mongo-data:/data/db javaxx:
image: java_compose:latest
restart: always
container_name: javaxx
ports:
- :
depends_on:
- postgresxx
- redisxx
- mymongoxx
environment:
- REDIS_HOST=redisxx //host注意:只写容器名字,不用加http://
- REDIS_PORT=
- POSTGRES_URL=postgresql://postgresxx:5432/testdb?useSSL=false //注意,没有http://
- POSTGRES_USERNAME=testdb
- POSTGRES_PASSWORD=testdb
- MONGO_URL=mongodb://testdb:testdb@mymongoxx:27017/
四、Nginx配置文件
因为使用docker容器,配置文件需要挂载
nginx.conf
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
proxy_ignore_client_abort on;
} server {
listen ;
server_name localhost; location / {
proxy_pass http://javaxx:9002;
proxy_set_header Host $proxy_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
} }
因为使用docker-compose部署,都是容器间通讯,所以地址都是容器的名字,javaxx就是项目容器名字(docker-compose.yml文件里面的container_name:javaxx)
五、环境变量
其实为了省事,环境变量都写在docker-compose.yml里面了,如果还有其他变量不方便写到yml文件里,可以写到.env文件,docker-compose.yml文件会去.env文件读取变量
六、docker-compose启动
进入到docker-compose目录,执行命令:
docker-compose -f docker-compose.yml up
停止:
docker-compose -f docker-compose.yml down
如果有容器启动失败,可以查看log,看看到底什么原因造成的
docker logs -f 容器名
OK,搞定
=============================分割线================================
主要代码:
application.properties
server.port= # Redis数据库索引(默认为0)
spring.redis.database=
# Redis服务器地址
spring.redis.host=${REDIS_HOST:localhost}
# Redis服务器连接端口
spring.redis.port=${REDIS_PORT:} #postgresql:
#DB properties:
spring.datasource.url=jdbc:${POSTGRES_URL:postgresql://localhost:5432/testdb?useSSL=false}
spring.datasource.username=${POSTGRES_USERNAME:testdb}
spring.datasource.password=${POSTGRES_PASSWORD:testdb}
spring.jpa.database-platform=org.hibernate.dialect.PostgreSQL9Dialect
spring.jpa.hibernate.ddl-auto=update
spring.jpa.generate-ddl=true spring.data.mongodb.uri=${MONGO_URL:mongodb://testdb:testdb@localhost:27017/}
spring.data.mongodb.database=testdb
# docker-compose 配置了MONGO_INITDB_ROOT_USERNAME和MONGO_INITDB_ROOT_PASSWORD,需要auth认证,这样就需要设置认证的数据库
# 同时配置了MONGO_INITDB_DATABASE=admin, 所以这里设置admin为认证数据库
spring.data.mongodb.authentication-database=admin
pom.xml:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.</modelVersion> <groupId>org.springframework</groupId>
<artifactId>gs-spring-boot</artifactId>
<version>0.1.</version> <parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5..RELEASE</version>
</parent> <dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency> <dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency> <dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<scope>runtime</scope>
</dependency> <dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency> <dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency> </dependencies> <properties>
<java.version>1.8</java.version>
</properties> <build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build> </project>
Application.java:
package com.main; import java.util.Arrays; import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ApplicationContext; @SpringBootApplication(scanBasePackages = {"com.main"}) //扫描com.main路径下的文件
public class Application { public static void main(String[] args) {
ApplicationContext ctx = SpringApplication.run(Application.class, args); System.out.println("Let's inspect the beans provided by Spring Boot:"); String[] beanNames = ctx.getBeanDefinitionNames();
Arrays.sort(beanNames);
for (String beanName : beanNames) {
System.out.println(beanName);
}
} }
--------
postgres相关:
ResponseUser.java:
package com.main.responseUser; import java.util.HashMap;
import java.util.Map; public class ResponseUser extends HashMap<String, Object> { private static final long serialVersionUID = 1L; public ResponseUser() {
put("code", );
} public static ResponseUser error(Integer code,String msg) {
return error(code, msg);
} public static ResponseUser error(int code, String msg) {
ResponseUser r = new ResponseUser();
r.put("code", code);
r.put("msg", msg);
return r;
} public static ResponseUser ok(Object msg) {
ResponseUser r = new ResponseUser();
r.put("msg", msg);
return r;
} public static ResponseUser ok(Map<String, Object> map) {
ResponseUser r = new ResponseUser();
r.putAll(map);
return r;
} public static ResponseUser ok() {
return new ResponseUser();
} @Override
public ResponseUser put(String key, Object value) {
super.put(key, value);
return this;
}
}
User.java:
package com.main.models; import java.io.Serializable; import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table; @Entity
@Table(name = "sys_user")
public class User implements Serializable{
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "id", nullable = false)
private Integer id;
@Column(nullable = false, name = "name")
private String name;
@Column(nullable = false, name = "age")
private Integer age; public static long getSerialVersionUID() {
return serialVersionUID;
} public Integer getId() {
return id;
} public void setId(Integer id) {
this.id = id;
} public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} public Integer getAge() {
return age;
} public void setAge(Integer age) {
this.age = age;
}
}
UserRepository.java:
package com.main.repository; import com.main.models.User;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param; import java.util.List; public interface UserRepository extends JpaRepository<User, Long> {
// 查
User findByName(String name); User findByAge(Integer age); List<User> findByNameAndAge(String name, Integer age); List<User> findByNameLike(String name); @Query("from User u where u.name=:name")
User findUser(@Param("name") String name); // 改
@Modifying
@Query("update User u set u.age=:age where u.id=:id")
void findByUpdateUser(@Param("id") Integer id,@Param("age") Integer age); // 删除的两种方式
User findById(Integer id);
void delete(User obj); @Modifying
@Query("delete from User u where u.id=:id")
void findByIdDeleteUser(@Param("id") Integer id); }
UserService.java:
package com.main.service; public class UserService { }
UserController.java:
package com.main.controllers; import com.main.models.User;
import com.main.repository.UserRepository;
import com.main.responseUser.ResponseUser;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.*;
import javax.transaction.Transactional;
import java.util.List; @Service
@RestController
@RequestMapping("/test")
public class UserContoller {
private final static Logger LOGGER = LoggerFactory.getLogger(UserContoller.class); @Autowired
private UserRepository userRepository; // 增
@PostMapping("/user")
public User saveUser(@RequestBody User us){
User user = new User();
user.setName(us.getName());
user.setAge(us.getAge());
userRepository.save(user);
return user;
} // 删
@Transactional
@DeleteMapping("/user/{id}")
public ResponseUser deleteUser(@PathVariable(name="id") Integer id) {
// User u = userRepository.findById(id);
// userRepository.delete(u);
// return u;
userRepository.findByIdDeleteUser(id);
return ResponseUser.ok();
} // 查询
@GetMapping("/users")
public List<User> searchUser(@RequestParam(name = "name") String name,@RequestParam(name = "age") Integer age){
LOGGER.info("获取");
List<User> u = userRepository.findByNameAndAge(name, age);
return u;
} // 改
@Transactional
@PutMapping("/user")
public ResponseUser updateUser(@RequestBody User us){
try{
userRepository.findByUpdateUser(us.getId(), us.getAge());
}catch (Exception e){
e.printStackTrace();
return ResponseUser.error(, "更新失败");
}
return ResponseUser.ok();
}
}
mongo相关:
Customer.java:
package com.main.models; import org.springframework.data.annotation.Id; public class Customer { @Id
public String id; public String firstName;
public String lastName; public String getId() {
return id;
} public void setId(String id) {
this.id = id;
} public String getFirstName() {
return firstName;
} public void setFirstName(String firstName) {
this.firstName = firstName;
} public String getLastName() {
return lastName;
} public void setLastName(String lastName) {
this.lastName = lastName;
} public Customer(String firstName, String lastName){
this.firstName = firstName;
this.lastName = lastName;
} @Override
public String toString(){
return String.format(
"Customer[id=%s, firstName='%s', lastName='%s']",
id, firstName, lastName
);
}
}
CustomerService.java:
package com.main.service; import com.main.models.Customer; public interface CustomerService { boolean insertCustomerIntoMongo(Customer ct); Customer getCustomerFromMongoByFirstName(String firstName); boolean updateCustomerToMongo(String firstName, String lastName); Customer deleteCustomerFromMongo(String firstName);
}
Impl/CustomerServiceImpl.java:
package com.main.service.Impl; import com.main.models.Customer;
import com.main.service.CustomerService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.stereotype.Service; @Service
public class CustomerServiceImpl implements CustomerService { protected static Logger logger = LoggerFactory.getLogger(CustomerServiceImpl.class); @Autowired
private MongoTemplate mongoTemplate; // 增
public boolean insertCustomerIntoMongo(Customer ct){
try{
mongoTemplate.save(ct);
return true;
}catch (Exception e){
logger.error("insertCustomerIntoMongo error: {}", e);
return false;
}
} // 查
public Customer getCustomerFromMongoByFirstName(String firstName){
Query query = new Query(Criteria.where("firstName").is(firstName));
Customer customer = mongoTemplate.findOne(query, Customer.class);
return customer;
} // 改
public boolean updateCustomerToMongo(String firstName, String lastName){
Query query = new Query(Criteria.where("firstName").is(firstName));
Update update = new Update();
update.set("lastName", lastName);
try {
mongoTemplate.updateFirst(query, update, Customer.class);
return true;
}catch (Exception e){
return false;
}
} // 删
public Customer deleteCustomerFromMongo(String firstName){
Customer customer = new Customer("小李", "飞刀1");
Query query = new Query(Criteria.where("firstName").is(firstName));
mongoTemplate.findAndRemove(query, Customer.class);
return customer;
}
}
CustomerController.java:
package com.main.controllers; import com.main.models.Customer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*;
import com.main.service.CustomerService; import java.util.Map; @RestController
@RequestMapping("/test")
public class CustomerController { private final static Logger LOGGER = LoggerFactory.getLogger(CustomerController.class); @Autowired
private CustomerService customerService; // 增
@PostMapping("customer")
public boolean save(@RequestBody(required = true)Map<String, Object> map){
String firstName = map.get("firstName").toString();
String lastName = map.get("lastName").toString();
Customer customer = new Customer(firstName, lastName);
boolean status = customerService.insertCustomerIntoMongo(customer);
return status;
} // 查
@GetMapping("/customer")
public Customer get(@RequestParam(name = "firstName") String firstName){
Customer customer = customerService.getCustomerFromMongoByFirstName(firstName);
return customer;
} // 改
@PutMapping("/customer")
public boolean update(@RequestBody(required = true)Map<String, Object> map){
String firstName = map.get("firstName").toString();
String lastName = map.get("lastName").toString();
boolean status = customerService.updateCustomerToMongo(firstName, lastName);
return status;
} // 删
@DeleteMapping("/customer")
public Customer delete(@RequestParam(name = "firstName") String firstName){
Customer customer = customerService.deleteCustomerFromMongo(firstName);
return customer;
}
}
CustomerRepository.java:
package com.main.repository; import com.main.models.Customer;
import org.bson.types.ObjectId;
import org.springframework.data.mongodb.repository.MongoRepository;
import org.springframework.stereotype.Repository; import java.util.List; @Repository
public interface CustomerRepository extends MongoRepository<Customer, ObjectId> {
// // 查询
// Customer findByFirstName(String firstName);
// List<Customer> findByLastName(String lastName);
//
// // 改
//
// // 删
// void delete(Customer obj);
}
redis操作相关:
RedisService.java:
package com.main.service; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component; @Component
public class RedisService {
@Autowired
private StringRedisTemplate redisTemp; public boolean set(String key, String value){
try{
redisTemp.opsForValue().set(key, value);
return true;
}catch(Exception e){
e.printStackTrace();
return false;
}
} public String get(String key){
return redisTemp.opsForValue().get(key);
}
}
RedisController.java:
package com.main.controllers; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.RequestMapping;
import com.main.service.RedisService; @RestController
@RequestMapping(value = "/test/redis",method = RequestMethod.GET)
public class RedisController {
@Autowired
private RedisService redisService; @RequestMapping("/set")
public String set(){
redisService.set("key1", "value1");
return "ok";
} @RequestMapping("/get")
public String get(){
String value = redisService.get("key1");
return value;
}
}
spring-boot-nginx代理-docker-compose部署的更多相关文章
- Spring Boot 2.0(五):Docker Compose + Spring Boot + Nginx + Mysql 实践
我知道大家这段时间看了我写关于 docker 相关的几篇文章,不疼不痒的,仍然没有感受 docker 的便利,是的,我也是这样认为的,I know your felling . 前期了解概念什么的确实 ...
- (转)Spring Boot 2 (五):Docker Compose + Spring Boot + Nginx + Mysql 实践
http://www.ityouknow.com/springboot/2018/03/28/dockercompose-springboot-mysql-nginx.html 我知道大家这段时间看了 ...
- Spring Boot 2 (五):Docker Compose + Spring Boot + Nginx + Mysql 实践
Spring Boot 2 (五):Docker Compose + Spring Boot + Nginx + Mysql 实践 Spring Boot + Nginx + Mysql 是实际工作中 ...
- Docker Compose + Spring Boot + Nginx + Mysql
Docker Compose + Spring Boot + Nginx + Mysql 实践 我知道大家这段时间看了我写关于 docker 相关的几篇文章,不疼不痒的,仍然没有感受 docker 的 ...
- 学习Spring Boot:(二十三)Spring Boot 中使用 Docker
前言 简单的学习下怎么在 Spring Boot 中使用 Docker 进行构建,发布一个镜像,现在我们通过远程的 docker api 构建镜像,运行容器,发布镜像等操作. 这里只介绍两种方式: 远 ...
- Docker Compose 部署前后端分离应用
部署前后端分离应用 容器化 Abp 应用 关于 Abp 应用的容器化,其实和普通的 ASP.NET Core 应用差不多,大家可以参考我此前的文章. 唯一需要注意的是:因为 Abp 解决方案中有多个项 ...
- Docker Compose部署GitLab服务,搭建自己的代码托管平台(图文教程)
场景 Docker-Compose简介与Ubuntu Server 上安装Compose: https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/deta ...
- Docker Compose 部署 Redis 及原理讲解 | 懒人屋
原文:Docker Compose 部署 Redis 及原理讲解 | 懒人屋 Docker Compose 部署 Redis 及原理讲解 4.4k 字 16 分钟 2019-10-1 ...
- spring boot hello and docker
主要是想试下spring boot运行在docker里的感觉, 小试牛刀 :) 这是原文,参考一下: https://spring.io/guides/gs/spring-boot-docker ...
- 使用Docker Compose部署基于Sentinel的高可用Redis集群
使用Docker Compose部署基于Sentinel的高可用Redis集群 https://yq.aliyun.com/articles/57953 Docker系列之(五):使用Docker C ...
随机推荐
- CPP-基础:关于内存分配
1:c中的malloc和c++中的new有什么区别 (1)new.delete 是操作符,可以重载,只能在C++中使用.(2)malloc.free是函数,可以覆盖,C.C++中都可以使用.(3)ne ...
- 解决wpf popup控件遮挡其他程序的问题
public class PopupNonTopmost : Popup { public static DependencyProperty TopmostProperty = Window.Top ...
- POI转换word doc文件为(html,xml,txt)
在POI中还存在有针对于word doc文件进行格式转换的功能.我们可以将word的内容转换为对应的Html文件,也可以把它转换为底层用来描述doc文档的xml文件,还可以把它转换为底层用来描述doc ...
- Bootstrap历练实例:超小的按钮
<!DOCTYPE html><html><head> <meta http-equiv="Content-Type" content=& ...
- JavaScript设计模式基础之闭包(终)
对于前端程序员来说闭包还是比较难以理解的, 闭包的形成与变量的作用域以及变量的生产周期密切相关,所以要先弄懂变量的作用域和生存周期. 1.变量作用域 变量的作用域,就是指变量的有效范围,通常我们指的作 ...
- vue-router介绍及简单使用
一.vue-router介绍 vue-router是vue官方提供的一个路由框架,控制页面路由,使用较为方便. 1.路由模式 hash(浏览器环境默认值),使用 URL hash 值来作路由,支持所有 ...
- H5新人福音~零配置搭建现代化的前端工程
X-BUILD一套基于Webpack(v4.21.0)快速搭建H5场景开发环境的脚手架,只需要几分钟的时间就可以运行起来.X-BUILD是针对H5开发的一套自动化构建工具,致力于提升开发效率,减小开发 ...
- 【编码】【转发】enca 转换编码
enca用法如下: enca -L zh_CN file 检查文件的编码 enca -L zh_CN -x UTF-8 file 将文件编码转换为"UTF-8"编码 enca -L ...
- c++ 整数读入优化
这个函数!!!! 它真的巨好用!!! 改了两天 换了两个版本的代码 都TLE了 然后尝试着在文件头加了这个替换了cin和scanf 结果意外地发现两个文件都突然能过了??? 太神奇了叭! 强烈安利! ...
- CSS 媒体查询 响应式
媒体查询 从 CSS 版本 2 开始,就可以通过媒体类型在 CSS 中获得媒体支持.如果您曾经使用过打印样式表,那么您可能已经使用过媒体类型.清单 1 展示了一个示例. 清单 1. 使用媒体类型 &l ...