capistrano3-ubuntu-server-prepare 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: c1fe1f7b1282af103530abc20eafec876fdcbdf1
4
+ data.tar.gz: 95cbd7717c834ec58b8dbde21b37fc631ae2659b
5
+ SHA512:
6
+ metadata.gz: 04efad9be18d41106de0be0deb33f94050ac739a8935279304ba01d11e0edc1a2e3b34e65d60db41702bb0e9c1fe1a17cb91d71b64b8ea5b9e356f44ba01ede0
7
+ data.tar.gz: 25bda5d0620e33d84b370f0de30b92c16065af5dbf0e86a930cc3b96add93c55dfc1c886c5c2a693d79c5b322512509f1171f25fe437c93f414e354c60437fb0
data/.gitignore ADDED
@@ -0,0 +1,14 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+ *.bundle
11
+ *.so
12
+ *.o
13
+ *.a
14
+ mkmf.log
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in capistrano-ubuntu-server-prepare.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 goooseman
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,176 @@
1
+ # capistrano3-ubuntu-server-prepare
2
+
3
+ This Capistrano (v3) task helps you to configure your blank ubuntu server before your first deploy.
4
+
5
+ It can:
6
+ * Make SSH more secure ('PermitRootLogin no', 'UseDNS no', 'AllowUsers username' SSH settings)
7
+ * Make swap (It asks for the size, default is 512k)
8
+ * Update and upgrade your server
9
+ * Install NGINX from source with or without Pagespeed module
10
+ * Install PostgreSQL and create user (It asks for db username and password)
11
+ * Install Redis
12
+ * Install RVM with latest Ruby, Rails and Bundler
13
+ * Copy your private ssh key (so you can login to your private git repo like BitBucket from the server)
14
+ * Install imagemagick (Needed by Paperclip)
15
+ * Install any additional Ubuntu packages (It asks which exactly)
16
+
17
+ You can run configuration wizard, which will ask you what to do and for some additional settings, and will do all the work, so you can go and drink some coffee. Or you can look at the source and run any of the tasks on its own.
18
+
19
+ Note! It requires nginx, redis and unicorn config files in 'config/production' folder of your project. You can get them by running ``` rake ubuntu_server_prepare:copy_config ```
20
+
21
+ **Attention!** My nginx and unicorn configuration files are made for your application running from /var/www/application/current. So add ``` set :application, 'application' ``` to your ``` config/deploy.rb ``` before first deploy or edit the configs.
22
+
23
+ For a complete usage instructions see [usage](#usage)
24
+
25
+ ## Installation
26
+
27
+ Add this line to your application's Gemfile:
28
+
29
+ ```ruby
30
+ group :development do
31
+ gem 'capistrano'
32
+ gem 'capistrano3-ubuntu-server-prepare'
33
+ end
34
+ ```
35
+
36
+ And then execute:
37
+
38
+ $ bundle
39
+
40
+ Run
41
+ ``` ruby
42
+ rake ubuntu_server_prepare:copy_config
43
+ ```
44
+ and edit config files in ``` config/production ```
45
+
46
+ Add
47
+ ``` ruby
48
+ require 'capistrano3/ubuntu-server-prepare'
49
+ ```
50
+ to your ``` Capfile ``` (If non exists run ``` cap install ```).
51
+
52
+
53
+ ## Usage
54
+
55
+ Just imagine: you have some blank Ubuntu server. All you need to do manually is creating not root user, ``` visudo```ing it and copying ssh keys, so you can login from your local machine without password.
56
+
57
+ So login as root to your server and do the following:
58
+
59
+ * ``` adduser deployer ``` (name can be anything)
60
+ * ``` echo "deployer ALL=(ALL) ALL" >> /etc/sudoers ``` (change deployer to your name)
61
+
62
+ On your local machine:
63
+
64
+ * ``` ssh-copy-id deployer@111.111.111.111 ``` (change deployer to your username and 111.111.111.111 to your server ip)
65
+ * Add
66
+ ``` ruby
67
+ group :development do
68
+ gem 'capistrano'
69
+ gem 'capistrano3-ubuntu-server-prepare'
70
+ end
71
+ ```
72
+ to your project ``` Gemfile ```
73
+ * Run ``` bundle install ``` from your project folder
74
+ * Run ``` rake ubuntu_server_prepare:copy_config ```
75
+ * Edit ``` config/production ``` config files, if you want
76
+ * Add ``` require 'capistrano3/ubuntu-server-prepare' ``` to your ``` Capfile ``` (``` cap install ``` if there isn't any)
77
+ * Be sure that line ``` require 'capistrano/rvm' ``` in your ``` Capfile ``` is commented.You can uncomment it after the process finishes.
78
+ * Edit ``` config/deploy/production.rb ``` so the only uncommented line will looks like
79
+ ``` ruby
80
+ server '111.111.111.111', user: 'deployer', roles: %w{web app db}
81
+ ```
82
+ * Run ``` cap production ubuntu_server_prepare ``` to run configuration wizard
83
+ * Answer all the questions and go to drink some coffee
84
+
85
+ **Attention!** My nginx and unicorn configuration files are made for your application running from /var/www/application/current. So add ``` set :application, 'application' ``` to your ``` config/deploy.rb ``` before first deploy or edit the configs.
86
+
87
+ ## What to do next?
88
+
89
+ So your server is configured, what to do next? How to deploy your app? OK, it is really easy:
90
+
91
+ * Be sure that settings for production are right in ``` db/database.yml ```
92
+ * Open your ``` Gemfile ``` and be sure you have these gems:
93
+ ``` ruby
94
+ group :development do
95
+ gem 'capistrano'
96
+ gem 'capistrano-rails'
97
+ gem 'capistrano-bundler'
98
+ gem 'capistrano3-unicorn'
99
+ gem 'capistrano-rvm'
100
+ gem 'capistrano3-ubuntu-server-prepare'
101
+ gem 'capistrano3-git-push'
102
+ end
103
+ group :production do
104
+ gem 'unicorn'
105
+ end
106
+ ```
107
+ * Open your ``` Capfile ``` and be sure you have these lines:
108
+ ``` ruby
109
+ # Load DSL and set up stages
110
+ require 'capistrano/setup'
111
+
112
+ # Include default deployment tasks
113
+ require 'capistrano/deploy'
114
+ require 'capistrano3/ubuntu-server-prepare'
115
+ require 'capistrano3/unicorn'
116
+ require 'capistrano3/git-push'
117
+ require 'capistrano/rvm'
118
+ require 'capistrano/bundler'
119
+ require 'capistrano/rails'
120
+ ```
121
+ * Open ``` config/deploy.rb ``` and paste your git server address in ``` set :repo_url ``` (You can use [BitBucket](https://bitbucket.org) for a good free private repository)
122
+ * Add
123
+ ``` ruby
124
+ set :unicorn_config_path, "#{current_path}/config/production/unicorn/unicorn.rb"
125
+ ```
126
+ * Add
127
+ ``` ruby
128
+ set :linked_dirs, fetch(:linked_dirs, []).push('bin', 'log', 'tmp/pids', 'tmp/cache', 'tmp/sockets', 'vendor/bundle', 'public/system')
129
+ ```
130
+
131
+ * Add
132
+ ``` ruby
133
+ task :setup do
134
+ before "deploy:migrate", :create_db
135
+ invoke :deploy
136
+ end
137
+
138
+ task :create_db do
139
+ on roles(:all) do
140
+ within release_path do
141
+ with rails_env: fetch(:rails_env) do
142
+ execute :rake, "db:create"
143
+ end
144
+ end
145
+ end
146
+ end
147
+ ```
148
+ right after ``` namespace :deploy do ``` line
149
+ * Add
150
+ ``` ruby
151
+ before :deploy, 'git:push'
152
+ before 'deploy:setup', 'git:push'
153
+
154
+ after 'deploy:publishing', 'deploy:restart'
155
+ namespace :deploy do
156
+ task :restart do
157
+ invoke 'unicorn:legacy_restart'
158
+ end
159
+ end
160
+ ```
161
+ to the end of the file
162
+ * Run ``` cap production deploy:setup ``` for the first time (it will run rake db:create), next times use ``` cap production deploy ```
163
+
164
+ ## Folder Structure
165
+ ```
166
+ /usr/local/nginx/conf/nginx.conf # NGINX conf
167
+ /etc/redis/ # Redis conf
168
+ /var/www/
169
+ -- log/ # Nginx and Redis log files here
170
+ -- run/ # Nginx and Redis pid files here
171
+ -- application/
172
+ ---- current/ # Your Rails app
173
+ ------ log/ # Rails and Unicorn log file here
174
+ ------ tmp/pids/ # Unicorn pid files here
175
+ ------ tmp/sockets/ # Unicorn socket files here
176
+ ```
data/Rakefile ADDED
@@ -0,0 +1,2 @@
1
+ require "bundler/gem_tasks"
2
+
@@ -0,0 +1,23 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = "capistrano3-ubuntu-server-prepare"
7
+ spec.version = "0.0.1"
8
+ spec.authors = ["goooseman"]
9
+ spec.email = ["inbox@goooseman.ru"]
10
+ spec.summary = "A task for Capistrano v3 to prepare Ubuntu 14.04 server for first deployment"
11
+ spec.description = "Can install nginx, ngx_pagespeed, postgreSQL, Redis, RVM, Ruby, Rails, Bundler"
12
+ spec.homepage = "http://github.com/goooseman/capistrano3-ubuntu-server-prepare"
13
+ spec.license = "MIT"
14
+
15
+ spec.files = `git ls-files -z`.split("\x0")
16
+ spec.require_paths = ["lib"]
17
+
18
+ spec.add_dependency "highline"
19
+
20
+ spec.add_development_dependency "bundler", "~> 1.7"
21
+ spec.add_development_dependency "rake", "~> 10.0"
22
+ spec.add_runtime_dependency 'capistrano', '~> 3.1', '>= 3.1.0'
23
+ end
@@ -0,0 +1,136 @@
1
+ user nginx web;
2
+
3
+ pid /var/www/run/nginx.pid;
4
+ error_log /var/www/log/nginx.error.log;
5
+
6
+ events {
7
+ worker_connections 1024; # increase if you have lots of clients
8
+ accept_mutex off; # "on" if nginx worker_processes > 1
9
+ use epoll; # enable for Linux 2.6+
10
+ # use kqueue; # enable for FreeBSD, OSX
11
+ }
12
+
13
+ http {
14
+ # nginx will find this file in the config directory set at nginx build time
15
+ include mime.types;
16
+ types_hash_max_size 2048;
17
+ server_names_hash_bucket_size 64;
18
+ # fallback in case we can't determine a type
19
+ default_type application/octet-stream;
20
+
21
+ # click tracking!
22
+ access_log /var/www/log/nginx.access.log combined;
23
+
24
+ # you generally want to serve static files with nginx since neither
25
+ # Unicorn nor Rainbows! is optimized for it at the moment
26
+ sendfile on;
27
+
28
+ tcp_nopush on; # off may be better for *some* Comet/long-poll stuff
29
+ tcp_nodelay off; # on may be better for some Comet/long-poll stuff
30
+
31
+ # we haven't checked to see if Rack::Deflate on the app server is
32
+ # faster or not than doing compression via nginx. It's easier
33
+ # to configure it all in one place here for static files and also
34
+ # to disable gzip for clients who don't get gzip/deflate right.
35
+ # There are other gzip settings that may be needed used to deal with
36
+ # bad clients out there, see http://wiki.nginx.org/NginxHttpGzipModule
37
+ gzip on;
38
+ gzip_http_version 1.0;
39
+ gzip_proxied any;
40
+ gzip_min_length 0;
41
+ gzip_vary on;
42
+ gzip_disable "MSIE [1-6]\.";
43
+ gzip_proxied expired no-cache no-store private auth;
44
+ gzip_comp_level 9;
45
+ gzip_types text/plain text/xml text/css
46
+ text/comma-separated-values
47
+ text/javascript application/x-javascript
48
+ application/atom+xml;
49
+
50
+ # this can be any application server, not just Unicorn/Rainbows!
51
+ upstream app_server {
52
+ server unix:/var/www/application/current/tmp/sockets/.unicorn.sock fail_timeout=0;
53
+ }
54
+
55
+ server {
56
+
57
+
58
+
59
+ charset utf-8;
60
+ # enable one of the following if you're on Linux or FreeBSD
61
+ listen 80 default deferred; # for Linux
62
+ # listen 80 default accept_filter=httpready; # for FreeBSD
63
+
64
+ # If you have IPv6, you'll likely want to have two separate listeners.
65
+ # One on IPv4 only (the default), and another on IPv6 only instead
66
+ # of a single dual-stack listener. A dual-stack listener will make
67
+ # for ugly IPv4 addresses in $remote_addr (e.g ":ffff:10.0.0.1"
68
+ # instead of just "10.0.0.1") and potentially trigger bugs in
69
+ # some software.
70
+ # listen [::]:80 ipv6only=on; # deferred or accept_filter recommended
71
+
72
+ client_max_body_size 4G;
73
+ server_name _;
74
+
75
+ # ~2 seconds is often enough for most folks to parse HTML/CSS and
76
+ # retrieve needed images/icons/frames, connections are cheap in
77
+ # nginx so increasing this is generally safe...
78
+ keepalive_timeout 5;
79
+
80
+ # path for static files
81
+ root /var/www/application/current/public;
82
+
83
+ # Prefer to serve static files directly from nginx to avoid unnecessary
84
+ # data copies from the application server.
85
+ #
86
+ # try_files directive appeared in in nginx 0.7.27 and has stabilized
87
+ # over time. Older versions of nginx (e.g. 0.6.x) requires
88
+ # "if (!-f $request_filename)" which was less efficient:
89
+ # http://bogomips.org/unicorn.git/tree/examples/nginx.conf?id=v3.3.1#n127
90
+ try_files $uri/index.html $uri.html $uri @app;
91
+
92
+ location ~ ^/(assets)/ {
93
+ root /var/www/application/current/public;
94
+
95
+ expires max;
96
+ add_header Cache-Control public;
97
+ }
98
+ location @app {
99
+ # an HTTP header important enough to have its own Wikipedia entry:
100
+ # http://en.wikipedia.org/wiki/X-Forwarded-For
101
+ proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
102
+
103
+ # enable this if you forward HTTPS traffic to unicorn,
104
+ # this helps Rack set the proper URL scheme for doing redirects:
105
+ # proxy_set_header X-Forwarded-Proto $scheme;
106
+
107
+ # pass the Host: header from the client right along so redirects
108
+ # can be set properly within the Rack application
109
+ proxy_set_header Host $http_host;
110
+
111
+ # we don't want nginx trying to do something clever with
112
+ # redirects, we set the Host: header above already.
113
+ proxy_redirect off;
114
+
115
+ # set "proxy_buffering off" *only* for Rainbows! when doing
116
+ # Comet/long-poll/streaming. It's also safe to set if you're using
117
+ # only serving fast clients with Unicorn + nginx, but not slow
118
+ # clients. You normally want nginx to buffer responses to slow
119
+ # clients, even with Rails 3.1 streaming because otherwise a slow
120
+ # client can become a bottleneck of Unicorn.
121
+ #
122
+ # The Rack application may also set "X-Accel-Buffering (yes|no)"
123
+ # in the response headers do disable/enable buffering on a
124
+ # per-response basis.
125
+ # proxy_buffering off;
126
+
127
+ proxy_pass http://app_server;
128
+ }
129
+
130
+ # Rails error pages
131
+ error_page 500 502 503 504 /500.html;
132
+ location = /500.html {
133
+ root /var/www/application/current/public;
134
+ }
135
+ }
136
+ }
@@ -0,0 +1,160 @@
1
+ user nginx web;
2
+
3
+ pid /var/www/run/nginx.pid;
4
+ error_log /var/www/log/nginx.error.log;
5
+
6
+ events {
7
+ worker_connections 1024; # increase if you have lots of clients
8
+ accept_mutex off; # "on" if nginx worker_processes > 1
9
+ use epoll; # enable for Linux 2.6+
10
+ # use kqueue; # enable for FreeBSD, OSX
11
+ }
12
+
13
+ http {
14
+ # nginx will find this file in the config directory set at nginx build time
15
+ include mime.types;
16
+ types_hash_max_size 2048;
17
+ server_names_hash_bucket_size 64;
18
+ # fallback in case we can't determine a type
19
+ default_type application/octet-stream;
20
+
21
+ # click tracking!
22
+ access_log /var/www/log/nginx.access.log combined;
23
+
24
+ # you generally want to serve static files with nginx since neither
25
+ # Unicorn nor Rainbows! is optimized for it at the moment
26
+ sendfile on;
27
+
28
+ tcp_nopush on; # off may be better for *some* Comet/long-poll stuff
29
+ tcp_nodelay off; # on may be better for some Comet/long-poll stuff
30
+
31
+ # we haven't checked to see if Rack::Deflate on the app server is
32
+ # faster or not than doing compression via nginx. It's easier
33
+ # to configure it all in one place here for static files and also
34
+ # to disable gzip for clients who don't get gzip/deflate right.
35
+ # There are other gzip settings that may be needed used to deal with
36
+ # bad clients out there, see http://wiki.nginx.org/NginxHttpGzipModule
37
+ gzip on;
38
+ gzip_http_version 1.0;
39
+ gzip_proxied any;
40
+ gzip_min_length 0;
41
+ gzip_vary on;
42
+ gzip_disable "MSIE [1-6]\.";
43
+ gzip_proxied expired no-cache no-store private auth;
44
+ gzip_comp_level 9;
45
+ gzip_types text/plain text/xml text/css
46
+ text/comma-separated-values
47
+ text/javascript application/x-javascript
48
+ application/atom+xml;
49
+
50
+ # this can be any application server, not just Unicorn/Rainbows!
51
+ upstream app_server {
52
+ server unix:/var/www/application/current/tmp/sockets/.unicorn.sock fail_timeout=0;
53
+ }
54
+
55
+ server {
56
+ # PageSpeed
57
+ pagespeed on;
58
+ pagespeed FileCachePath /var/ngx_pagespeed_cache;
59
+ location ~ "\.pagespeed\.([a-z]\.)?[a-z]{2}\.[^.]{10}\.[^.]+" {
60
+ add_header "" "";
61
+ }
62
+ location ~ "^/ngx_pagespeed_static/" { }
63
+ location ~ "^/ngx_pagespeed_beacon$" { }
64
+ location /ngx_pagespeed_statistics {
65
+ allow 127.0.0.1; allow 5.228.169.73; deny all;
66
+ }
67
+ location /ngx_pagespeed_global_statistics {
68
+ allow 127.0.0.1; allow 5.228.169.73; deny all;
69
+ }
70
+ pagespeed MessageBufferSize 100000;
71
+ location /ngx_pagespeed_message {
72
+ allow 127.0.0.1; allow 5.228.169.73; deny all;
73
+ }
74
+ location /pagespeed_console {
75
+ allow 127.0.0.1; allow 5.228.169.73; deny all;
76
+ }
77
+
78
+
79
+
80
+
81
+
82
+
83
+ charset utf-8;
84
+ # enable one of the following if you're on Linux or FreeBSD
85
+ listen 80 default deferred; # for Linux
86
+ # listen 80 default accept_filter=httpready; # for FreeBSD
87
+
88
+ # If you have IPv6, you'll likely want to have two separate listeners.
89
+ # One on IPv4 only (the default), and another on IPv6 only instead
90
+ # of a single dual-stack listener. A dual-stack listener will make
91
+ # for ugly IPv4 addresses in $remote_addr (e.g ":ffff:10.0.0.1"
92
+ # instead of just "10.0.0.1") and potentially trigger bugs in
93
+ # some software.
94
+ # listen [::]:80 ipv6only=on; # deferred or accept_filter recommended
95
+
96
+ client_max_body_size 4G;
97
+ server_name _;
98
+
99
+ # ~2 seconds is often enough for most folks to parse HTML/CSS and
100
+ # retrieve needed images/icons/frames, connections are cheap in
101
+ # nginx so increasing this is generally safe...
102
+ keepalive_timeout 5;
103
+
104
+ # path for static files
105
+ root /var/www/application/current/public;
106
+
107
+ # Prefer to serve static files directly from nginx to avoid unnecessary
108
+ # data copies from the application server.
109
+ #
110
+ # try_files directive appeared in in nginx 0.7.27 and has stabilized
111
+ # over time. Older versions of nginx (e.g. 0.6.x) requires
112
+ # "if (!-f $request_filename)" which was less efficient:
113
+ # http://bogomips.org/unicorn.git/tree/examples/nginx.conf?id=v3.3.1#n127
114
+ try_files $uri/index.html $uri.html $uri @app;
115
+
116
+ location ~ ^/(assets)/ {
117
+ root /var/www/application/current/public;
118
+
119
+ expires max;
120
+ add_header Cache-Control public;
121
+ }
122
+ location @app {
123
+ # an HTTP header important enough to have its own Wikipedia entry:
124
+ # http://en.wikipedia.org/wiki/X-Forwarded-For
125
+ proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
126
+
127
+ # enable this if you forward HTTPS traffic to unicorn,
128
+ # this helps Rack set the proper URL scheme for doing redirects:
129
+ # proxy_set_header X-Forwarded-Proto $scheme;
130
+
131
+ # pass the Host: header from the client right along so redirects
132
+ # can be set properly within the Rack application
133
+ proxy_set_header Host $http_host;
134
+
135
+ # we don't want nginx trying to do something clever with
136
+ # redirects, we set the Host: header above already.
137
+ proxy_redirect off;
138
+
139
+ # set "proxy_buffering off" *only* for Rainbows! when doing
140
+ # Comet/long-poll/streaming. It's also safe to set if you're using
141
+ # only serving fast clients with Unicorn + nginx, but not slow
142
+ # clients. You normally want nginx to buffer responses to slow
143
+ # clients, even with Rails 3.1 streaming because otherwise a slow
144
+ # client can become a bottleneck of Unicorn.
145
+ #
146
+ # The Rack application may also set "X-Accel-Buffering (yes|no)"
147
+ # in the response headers do disable/enable buffering on a
148
+ # per-response basis.
149
+ # proxy_buffering off;
150
+
151
+ proxy_pass http://app_server;
152
+ }
153
+
154
+ # Rails error pages
155
+ error_page 500 502 503 504 /500.html;
156
+ location = /500.html {
157
+ root /var/www/application/current/public;
158
+ }
159
+ }
160
+ }