Closed iBug closed 4 years ago
Eh... I don't like Docker, personally, so I'd still deploy the manual way, meaning unless someone else was using it, the Dockerfile would end up being outdated and unmaintained. If others would find it useful then we might want to do this, but if nobody's going to use it there's probably little point.
I want to add :heavy_plus_sign: for support for Docker, it's the bread and butter to quick deployment on the cloud these days. It's also hugely useful to quickly bring up a development environment without mucking around with your host.
Given the previous comment, I don't see the harm in reopening this and waiting for someone who wants to work on it. It doesn't constrain the codidact.com deployment; it's just an option, right?
Exactly! +1 for re-opening, and if no one grabs this quickly, I can definitely do it. For some background of my use case (and interest) my group had tried creating a Stack Exchange and didn't make it through the final rounds. We ported to Discourse, but it's not really intended to be akin to a Stack Exchange (even with the voting plugin). Glancing over the deployments here, this seems closer to what my group had in mind to either, so I'm definitely eager to try it out (and in the process, Dockerize).
Works for me. All yours if you want it, @vsoch :)
heyo! I made good progress today, I'm hoping I can ask for a bit of your expertise.
I made sure to create the community that corresponds to where I'm running the rails server
# here is running the server
rails server -b 0.0.0.0
And creating the community via rails runner
rails runner "Community.create(name: \"$COMMUNITY_NAME\", host: '0.0.0.0:3000')"
I can also confirm that it exists running the same command with rails console:
# rails console
Running via Spring preloader in process 67
Loading development environment (Rails 5.2.4.3)
irb(main):001:0> Community.create(name: 'Dinosaur Community', host: '0.0.0.0:3000')
(0.5ms) SET NAMES utf8mb4 COLLATE utf8mb4_unicode_ci, @@SESSION.sql_mode = CONCAT(CONCAT(@@sql_mode, ',STRICT_ALL_TABLES'), ',NO_AUTO_VALUE_ON_ZERO'), @@SESSION.sql_auto_is_null = 0, @@SESSION.wait_timeout = 2147483
(0.2ms) BEGIN
Community Exists (0.5ms) SELECT 1 AS one FROM `communities` WHERE `communities`.`host` = BINARY '0.0.0.0:3000' LIMIT 1
(0.3ms) ROLLBACK
=> #<Community id: nil, name: "Dinosaur Community", host: "0.0.0.0:3000", created_at: nil, updated_at: nil>
but when I visit the portal, it indicates that it doesn't exist:
Looking at the code, it looks like it's looking in some kind of rails cache here?
def setup_request_context
RequestContext.clear!
host_name = request.raw_host_with_port # include port to support multiple localhost instances
RequestContext.community = @community = Rails.cache.fetch("#{host_name}/community", expires_in: 1.hour) do
Community.find_by(host: host_name)
end
Rails.logger.info " Host #{host_name}, community ##{RequestContext.community_id} " \
"(#{RequestContext.community&.name})"
unless RequestContext.community.present?
render status: 422, plain: "No community record matching Host='#{host_name}'"
return false
end
I also tried different variations of the host name, in case it was expecting different:
Running via Spring preloader in process 34
Loading development environment (Rails 5.2.4.3)
irb(main):001:0> Community.create(name: 'Dinosaur Community', host: '127.0.0.1:3000')
(1.3ms) SET NAMES utf8mb4 COLLATE utf8mb4_unicode_ci, @@SESSION.sql_mode = CONCAT(CONCAT(@@sql_mode, ',STRICT_ALL_TABLES'), ',NO_AUTO_VALUE_ON_ZERO'), @@SESSION.sql_auto_is_null = 0, @@SESSION.wait_timeout = 2147483
(0.8ms) BEGIN
Community Exists (10.9ms) SELECT 1 AS one FROM `communities` WHERE `communities`.`host` = BINARY '127.0.0.1:3000' LIMIT 1
Community Create (0.5ms) INSERT INTO `communities` (`name`, `host`, `created_at`, `updated_at`) VALUES ('Dinosaur Community', '127.0.0.1:3000', '2020-08-22 22:06:24', '2020-08-22 22:06:24')
(1.7ms) COMMIT
=> #<Community id: 2, name: "Dinosaur Community", host: "127.0.0.1:3000", created_at: "2020-08-22 22:06:24", updated_at: "2020-08-22 22:06:24">
irb(main):002:0> Community.create(name: 'Dinosaur Community', host: 'localhost:3000')
(0.8ms) BEGIN
Community Exists (1.1ms) SELECT 1 AS one FROM `communities` WHERE `communities`.`host` = BINARY 'localhost:3000' LIMIT 1
Community Create (1.0ms) INSERT INTO `communities` (`name`, `host`, `created_at`, `updated_at`) VALUES ('Dinosaur Community', 'localhost:3000', '2020-08-22 22:06:30', '2020-08-22 22:06:30')
(38.6ms) COMMIT
=> #<Community id: 3, name: "Dinosaur Community", host: "localhost:3000", created_at: "2020-08-22 22:06:30", updated_at: "2020-08-22 22:06:30">
irb(main):003:0> Community.create(name: 'Dinosaur Community', host: 'localhost')
(0.9ms) BEGIN
Community Exists (1.3ms) SELECT 1 AS one FROM `communities` WHERE `communities`.`host` = BINARY 'localhost' LIMIT 1
Community Create (1.1ms) INSERT INTO `communities` (`name`, `host`, `created_at`, `updated_at`) VALUES ('Dinosaur Community', 'localhost', '2020-08-22 22:06:48', '2020-08-22 22:06:48')
(13.1ms) COMMIT
=> #<Community id: 4, name: "Dinosaur Community", host: "localhost", created_at: "2020-08-22 22:06:48", updated_at: "2020-08-22 22:06:48">
irb(main):004:0> Community.create(name: 'Dinosaur Community', host: '0.0.0.0')
(0.8ms) BEGIN
Community Exists (1.2ms) SELECT 1 AS one FROM `communities` WHERE `communities`.`host` = BINARY '0.0.0.0' LIMIT 1
Community Create (1.1ms) INSERT INTO `communities` (`name`, `host`, `created_at`, `updated_at`) VALUES ('Dinosaur Community', '0.0.0.0', '2020-08-22 22:06:52', '2020-08-22 22:06:52')
(11.2ms) COMMIT
=> #<Community id: 5, name: "Dinosaur Community", host: "0.0.0.0", created_at: "2020-08-22 22:06:52", updated_at: "2020-08-22 22:06:52">
Perhaps a good question to start our debugging - how does this cache get populated (and where?).
Ah just found something, I think I need to add the docker host as an allowed network?
uwsgi_1 | Started GET "/" for 172.19.0.1 at 2020-08-22 22:08:14 +0000
uwsgi_1 | Cannot render console from 172.19.0.1! Allowed networks: 127.0.0.1, ::1, 127.0.0.0/127.255.255.255
uwsgi_1 | Processing by CategoriesController#homepage as HTML
uwsgi_1 | Host 0.0.0.0:3000, community # ()
uwsgi_1 | Rendering text template
uwsgi_1 | Rendered text template (0.0ms)
uwsgi_1 | Filter chain halted as :set_globals rendered or redirected
uwsgi_1 | Completed 422 Unprocessable Entity in 2ms (Views: 0.4ms | ActiveRecord: 0.0ms)
uwsgi_1 |
uwsgi_1 |
Yep, site associations are cached - if you've hit it once and failed, and then corrected it and tried again, you'll need to clear the cache before it'll work - run Rails.cache.clear
in a Rails console.
Cannot render console from 172.19.0.1!
That's an error from web_console
- it's a problem only if you want the terminal-in-webpage thingy that Rails provides. It's separate from getting the right community record.
Ok, I was able to add the docker container hostname, now I'm not seeing any obvious error:
uwsgi_1 |
uwsgi_1 |
uwsgi_1 | Started GET "/" for 172.19.0.1 at 2020-08-22 22:27:07 +0000
uwsgi_1 | Processing by CategoriesController#homepage as HTML
uwsgi_1 | Host 0.0.0.0:3000, community # ()
uwsgi_1 | Rendering text template
uwsgi_1 | Rendered text template (0.0ms)
uwsgi_1 | Filter chain halted as :set_globals rendered or redirected
uwsgi_1 | Completed 422 Unprocessable Entity in 1ms (Views: 0.3ms | ActiveRecord: 0.0ms)
uwsgi_1 |
uwsgi_1 |
I cleared the cache
irb(main):002:0> Rails.cache.clear
=> ["/code/tmp/cache/C62", "/code/tmp/cache/317", "/code/tmp/cache/E0A", "/code/tmp/cache/3E0", "/code/tmp/cache/C39", "/code/tmp/cache/D9F", "/code/tmp/cache/292", "/code/tmp/cache/BFD"]
I'm seeing something now!
Progress, haha.
Is there a way to programatically create an admin user? I don't think the container has the plumbing to send email.
User.create(username: 'xyz', password: 'xyz', email: 'xyz', is_global_admin: true)
should do it
Awesome! I seemed to fix the 500 error (not sure how but I'll try to reproduce it)
I'm not sure the create user command worked? I can't log in with the email / password I chose, and the query seems to return empty?
User.second
User Load (1.4ms) SELECT `users`.* FROM `users` ORDER BY `users`.`id` ASC LIMIT 1 OFFSET 1
=> nil
Note that User.first seems to be an anonymous system account.
Do I need to provide a hash? That at least seems to do something:
User.create(username: "username", password: Digest::SHA1.hexdigest("username"), email: "admin@domain.com", is_global_admin: true, is_global_moderator: true, staff: true)
But then I hit an error for sending a welcome email. Is there a setting to disable email sending?
(0.6ms) ROLLBACK
Traceback (most recent call last):
4: from (irb):2
3: from (irb):2:in `rescue in irb_binding'
2: from app/models/user.rb:195:in `send_welcome_tour_message'
1: from app/models/user.rb:195:in `+'
TypeError (no implicit conversion of nil into String)
irb(main):003:0>
Anyhoo, I'm probably stopping for today, thanks for helping me on the weekend! And definitely thanks for helping me learn a little more about Ruby on Rails.
Here is the branch if you want to take a look! https://github.com/researchapps/qpixel/tree/add/docker-compose Let me know if it would be easier for me to open a draft PR, definitely can do that.
What did the User.create
call return? That might help tell you something. The usual way of doing this is to create an account with the web interface, then upgrade it from the console, so I'm not well versed in the best way to do it all from a console.
It's the error I showed above about sending the email - here is the full command and result so you can see it. It looks like that error rolls it back?
User.create(username: "naa", password:"naa", email: "naa@a.com", is_global_admin: true, is_global_moderator: true, staff: true)
(1.5ms) SET NAMES utf8mb4 COLLATE utf8mb4_unicode_ci, @@SESSION.sql_mode = CONCAT(CONCAT(@@sql_mode, ',STRICT_ALL_TABLES'), ',NO_AUTO_VALUE_ON_ZERO'), @@SESSION.sql_auto_is_null = 0, @@SESSION.wait_timeout = 2147483
(0.2ms) BEGIN
User Exists (11.4ms) SELECT 1 AS one FROM `users` WHERE `users`.`email` = BINARY 'naa@a.com' LIMIT 1
SiteSetting Load (1.2ms) SELECT `site_settings`.* FROM `site_settings` WHERE `site_settings`.`community_id` IS NULL AND `site_settings`.`name` = 'AdminBadgeCharacter' ORDER BY IF(site_settings.community_id IS NULL, 1, 0) LIMIT 1
SiteSetting Load (0.8ms) SELECT `site_settings`.* FROM `site_settings` WHERE `site_settings`.`community_id` IS NULL AND `site_settings`.`name` = 'ModBadgeCharacter' ORDER BY IF(site_settings.community_id IS NULL, 1, 0) LIMIT 1
(0.1ms) ROLLBACK
(0.1ms) BEGIN
User Exists (0.3ms) SELECT 1 AS one FROM `users` WHERE `users`.`email` = BINARY 'naa@a.com' LIMIT 1
SiteSetting Load (0.4ms) SELECT `site_settings`.* FROM `site_settings` WHERE `site_settings`.`community_id` IS NULL AND `site_settings`.`name` = 'AdminBadgeCharacter' ORDER BY IF(site_settings.community_id IS NULL, 1, 0) LIMIT 1
SiteSetting Load (0.4ms) SELECT `site_settings`.* FROM `site_settings` WHERE `site_settings`.`community_id` IS NULL AND `site_settings`.`name` = 'ModBadgeCharacter' ORDER BY IF(site_settings.community_id IS NULL, 1, 0) LIMIT 1
(0.2ms) ROLLBACK
=> #<User id: nil, email: "naa@a.com", created_at: nil, updated_at: nil, is_global_moderator: true, is_global_admin: true, username: "naa", profile: nil, website: nil, twitter: nil, profile_markdown: nil, se_acct_id: nil, transferred_content: false, trust_level: 6, login_token: nil, login_token_expires_at: nil, two_factor_token: nil, enabled_2fa: false, two_factor_method: nil, staff: true
Sorry updated because I gave a call when it already existed!
The user is supposedly created but it's id is nil.
Sorry I haven't got back to this sooner, the last couple days have been super busy.
If you call create
and the result has id: nil
, there were validation or SQL errors while creating it - try running u = User.create(...)
, then u.errors.full_messages
- that should reveal any validation errors.
It was the weekend! Totally no worries. And ha, this message!
irb(main):002:0> u.errors.full_messages
=> ["Password is too short (minimum is 6 characters)"]
Now when I address that and make it >6 characters, I see that rollback error again, because the welcome email cannot be sent.
u = User.create(username: "noo", password:"naaaaaa", email: "noo@a.com", is_global_admin: true, is_global_moderator: true, staff: true)
(0.2ms) BEGIN
User Exists (0.3ms) SELECT 1 AS one FROM `users` WHERE `users`.`email` = BINARY 'noo@a.com' LIMIT 1
SiteSetting Load (0.2ms) SELECT `site_settings`.* FROM `site_settings` WHERE `site_settings`.`community_id` IS NULL AND `site_settings`.`name` = 'AdminBadgeCharacter' ORDER BY IF(site_settings.community_id IS NULL, 1, 0) LIMIT 1
SiteSetting Load (0.2ms) SELECT `site_settings`.* FROM `site_settings` WHERE `site_settings`.`community_id` IS NULL AND `site_settings`.`name` = 'ModBadgeCharacter' ORDER BY IF(site_settings.community_id IS NULL, 1, 0) LIMIT 1
User Create (0.2ms) INSERT INTO `users` (`email`, `encrypted_password`, `created_at`, `updated_at`, `is_global_moderator`, `is_global_admin`, `username`, `confirmation_token`, `confirmation_sent_at`, `staff`) VALUES ('noo@a.com', '$2a$11$RDkeuIvW4Izez8KkQKenV.LkeiPWlXgLXQyjI49N17T2PFw60u3/O', '2020-08-25 18:05:04', '2020-08-25 18:05:04', TRUE, TRUE, 'noo', '1xySKS-uiccs39qQfzf3', '2020-08-25 18:05:04', TRUE)
SiteSetting Load (0.2ms) SELECT `site_settings`.* FROM `site_settings` WHERE `site_settings`.`community_id` IS NULL AND `site_settings`.`name` = 'SiteName' ORDER BY IF(site_settings.community_id IS NULL, 1, 0) LIMIT 1
(1.0ms) ROLLBACK
Traceback (most recent call last):
3: from (irb):5
2: from app/models/user.rb:195:in `send_welcome_tour_message'
1: from app/models/user.rb:195:in `+'
TypeError (no implicit conversion of nil into String)
There isn't any new insight to look at the errors again because we don't return a new user object. Is there a way to either fix this welcome message functionality, or disable it?
Where are the SiteSettings defined? I think the issue might be that one of them is nil.
The error is about converting nil to a string, but the string in question isn't related to the user, I think it's a SiteSetting? Here is the error:
uwsgi_1 | /code/app/models/user.rb:195:in `+': no implicit conversion of nil into String (TypeError)
uwsgi_1 | from /code/app/models/user.rb:195:in `send_welcome_tour_message'
uwsgi_1 | from /usr/local/bundle/gems/activesupport-5.2.4.3/lib/active_support/callbacks.rb:426:in `block in make_lambda'
uwsgi_1 | from /usr/local/bundle/gems/activesupport-5.2.4.3/lib/active_support/callbacks.rb:236:in `block in halting_and_conditional'
uwsgi_1 | from /usr/local/bundle/gems/activesupport-5.2.4.3/lib/active_support/callbacks.rb:517:in `block in invoke_after'
uwsgi_1 | from /usr/local/bundle/gems/activesupport-5.2.4.3/lib/active_support/callbacks.rb:517:in `each'
uwsgi_1 | from /usr/local/bundle/gems/activesupport-5.2.4.3/lib/active_support/callbacks.rb:517:in `invoke_after'
uwsgi_1 | from /usr/local/bundle/gems/activesupport-5.2.4.3/lib/active_support/callbacks.rb:133:in `run_callbacks'
uwsgi_1 | from /usr/local/bundle/gems/activesupport-5.2.4.3/lib/active_support/callbacks.rb:816:in `_run_create_callbacks'
uwsgi_1 | from /usr/local/bundle/gems/activerecord-5.2.4.3/lib/active_record/callbacks.rb:346:in `_create_record'
uwsgi_1 | from /usr/local/bundle/gems/activerecord-5.2.4.3/lib/active_record/timestamp.rb:102:in `_create_record'
uwsgi_1 | from /usr/local/bundle/gems/activerecord-5.2.4.3/lib/active_record/persistence.rb:705:in `create_or_update'
uwsgi_1 | from /usr/local/bundle/gems/activerecord-5.2.4.3/lib/active_record/callbacks.rb:342:in `block in create_or_update'
uwsgi_1 | from /usr/local/bundle/gems/activesupport-5.2.4.3/lib/active_support/callbacks.rb:132:in `run_callbacks'
uwsgi_1 | from /usr/local/bundle/gems/activesupport-5.2.4.3/lib/active_support/callbacks.rb:816:in `_run_save_callbacks'
uwsgi_1 | from /usr/local/bundle/gems/activerecord-5.2.4.3/lib/active_record/callbacks.rb:342:in `create_or_update'
uwsgi_1 | from /usr/local/bundle/gems/activerecord-5.2.4.3/lib/active_record/persistence.rb:275:in `save'
uwsgi_1 | from /usr/local/bundle/gems/activerecord-5.2.4.3/lib/active_record/validations.rb:46:in `save'
uwsgi_1 | from /usr/local/bundle/gems/activerecord-5.2.4.3/lib/active_record/transactions.rb:310:in `block (2 levels) in save'
uwsgi_1 | from /usr/local/bundle/gems/activerecord-5.2.4.3/lib/active_record/transactions.rb:387:in `block in with_transaction_returning_status'
uwsgi_1 | from /usr/local/bundle/gems/activerecord-5.2.4.3/lib/active_record/connection_adapters/abstract/database_statements.rb:267:in `block in transaction'
uwsgi_1 | from /usr/local/bundle/gems/activerecord-5.2.4.3/lib/active_record/connection_adapters/abstract/transaction.rb:239:in `block in within_new_transaction'
uwsgi_1 | from /usr/local/lib/ruby/2.6.0/monitor.rb:235:in `mon_synchronize'
uwsgi_1 | from /usr/local/bundle/gems/activerecord-5.2.4.3/lib/active_record/connection_adapters/abstract/transaction.rb:236:in `within_new_transaction'
uwsgi_1 | from /usr/local/bundle/gems/activerecord-5.2.4.3/lib/active_record/connection_adapters/abstract/database_statements.rb:267:in `transaction'
uwsgi_1 | from /usr/local/bundle/gems/activerecord-5.2.4.3/lib/active_record/transactions.rb:212:in `transaction'
uwsgi_1 | from /usr/local/bundle/gems/activerecord-5.2.4.3/lib/active_record/transactions.rb:385:in `with_transaction_returning_status'
uwsgi_1 | from /usr/local/bundle/gems/activerecord-5.2.4.3/lib/active_record/transactions.rb:310:in `block in save'
uwsgi_1 | from /usr/local/bundle/gems/activerecord-5.2.4.3/lib/active_record/transactions.rb:325:in `rollback_active_record_state!'
uwsgi_1 | from /usr/local/bundle/gems/activerecord-5.2.4.3/lib/active_record/transactions.rb:309:in `save'
uwsgi_1 | from /usr/local/bundle/gems/activerecord-5.2.4.3/lib/active_record/suppressor.rb:44:in `save'
uwsgi_1 | from /usr/local/bundle/gems/activerecord-5.2.4.3/lib/active_record/persistence.rb:36:in `create'
uwsgi_1 | from /usr/local/bundle/gems/railties-5.2.4.3/lib/rails/commands/runner/runner_command.rb:41:in `<main>'
uwsgi_1 | from /usr/local/bundle/gems/railties-5.2.4.3/lib/rails/commands/runner/runner_command.rb:41:in `eval'
uwsgi_1 | from /usr/local/bundle/gems/railties-5.2.4.3/lib/rails/commands/runner/runner_command.rb:41:in `perform'
uwsgi_1 | from /usr/local/bundle/gems/thor-1.0.1/lib/thor/command.rb:27:in `run'
uwsgi_1 | from /usr/local/bundle/gems/thor-1.0.1/lib/thor/invocation.rb:127:in `invoke_command'
uwsgi_1 | from /usr/local/bundle/gems/thor-1.0.1/lib/thor.rb:392:in `dispatch'
uwsgi_1 | from /usr/local/bundle/gems/railties-5.2.4.3/lib/rails/command/base.rb:69:in `perform'
uwsgi_1 | from /usr/local/bundle/gems/railties-5.2.4.3/lib/rails/command.rb:46:in `invoke'
uwsgi_1 | from /usr/local/bundle/gems/railties-5.2.4.3/lib/rails/commands.rb:18:in `<top (required)>'
uwsgi_1 | from /usr/local/bundle/gems/activesupport-5.2.4.3/lib/active_support/dependencies.rb:291:in `require'
uwsgi_1 | from /usr/local/bundle/gems/activesupport-5.2.4.3/lib/active_support/dependencies.rb:291:in `block in require'
uwsgi_1 | from /usr/local/bundle/gems/activesupport-5.2.4.3/lib/active_support/dependencies.rb:257:in `load_dependency'
uwsgi_1 | from /usr/local/bundle/gems/activesupport-5.2.4.3/lib/active_support/dependencies.rb:291:in `require'
uwsgi_1 | from /code/bin/rails:9:in `<top (required)>'
uwsgi_1 | from /usr/local/bundle/gems/activesupport-5.2.4.3/lib/active_support/dependencies.rb:285:in `load'
uwsgi_1 | from /usr/local/bundle/gems/activesupport-5.2.4.3/lib/active_support/dependencies.rb:285:in `block in load'
uwsgi_1 | from /usr/local/bundle/gems/activesupport-5.2.4.3/lib/active_support/dependencies.rb:257:in `load_dependency'
uwsgi_1 | from /usr/local/bundle/gems/activesupport-5.2.4.3/lib/active_support/dependencies.rb:285:in `load'
uwsgi_1 | from /usr/local/lib/ruby/2.6.0/rubygems/core_ext/kernel_require.rb:54:in `require'
uwsgi_1 | from /usr/local/lib/ruby/2.6.0/rubygems/core_ext/kernel_require.rb:54:in `require'
uwsgi_1 | from -e:1:in `<main>'
and here is the notification attempt:
def send_welcome_tour_message
return if id == -1
create_notification('👋 Welcome to ' + SiteSetting['SiteName'] + '! Take our tour to find out ' \
'how this site works.', '/tour')
end
So I wonder how SiteName is set?
Nah. The issue is, that there is no community here, because you're not on a request. Try going to the mentioned function and replacing SiteSetting['SiteName']
with (SiteSetting['SiteName'] || 'Codidact')
.
Gotcha! Cool that I caught the issue :)
Making progress! Now we get through that bug, and there is another issue that the community doesn't have an id:
u = User.create(username: "...", password:"...", email: "...", is_global_admin: true, is_global_moderator: true, staff: true)
(0.8ms) SET NAMES utf8mb4 COLLATE utf8mb4_unicode_ci, @@SESSION.sql_mode = CONCAT(CONCAT(@@sql_mode, ',STRICT_ALL_TABLES'), ',NO_AUTO_VALUE_ON_ZERO'), @@SESSION.sql_auto_is_null = 0, @@SESSION.wait_timeout = 2147483
(0.2ms) BEGIN
User Exists (0.4ms) SELECT 1 AS one FROM `users` WHERE `users`.`email` = BINARY 'pancakes@a.com' LIMIT 1
SiteSetting Load (0.4ms) SELECT `site_settings`.* FROM `site_settings` WHERE `site_settings`.`community_id` IS NULL AND `site_settings`.`name` = 'AdminBadgeCharacter' ORDER BY IF(site_settings.community_id IS NULL, 1, 0) LIMIT 1
SiteSetting Load (0.2ms) SELECT `site_settings`.* FROM `site_settings` WHERE `site_settings`.`community_id` IS NULL AND `site_settings`.`name` = 'ModBadgeCharacter' ORDER BY IF(site_settings.community_id IS NULL, 1, 0) LIMIT 1
User Create (0.4ms) INSERT INTO `users` (`email`, `encrypted_password`, `created_at`, `updated_at`, `is_global_moderator`, `is_global_admin`, `username`, `confirmation_token`, `confirmation_sent_at`, `staff`) VALUES ('pancakes@a.com', '$2a$11$t0LCKRfKjjW1eGkweB3bdeV1A45RZGBGKBmHKXivgyRl3kFvbxZpm', '2020-08-25 18:14:58', '2020-08-25 18:14:58', TRUE, TRUE, 'vanessa', 'bYYgC87gZRQzB3e5VgxG', '2020-08-25 18:14:58', TRUE)
SiteSetting Load (0.3ms) SELECT `site_settings`.* FROM `site_settings` WHERE `site_settings`.`community_id` IS NULL AND `site_settings`.`name` = 'SiteName' ORDER BY IF(site_settings.community_id IS NULL, 1, 0) LIMIT 1
Notification Create (0.9ms) INSERT INTO `notifications` (`content`, `link`, `created_at`, `updated_at`) VALUES ('👋 Welcome to Codidact! Take our tour to find out how this site works.', '/tour', '2020-08-25 18:14:58', '2020-08-25 18:14:58')
(3.8ms) ROLLBACK
Traceback (most recent call last):
3: from (irb):1
2: from app/models/user.rb:195:in `send_welcome_tour_message'
1: from app/models/user.rb:70:in `create_notification'
ActiveRecord::NotNullViolation (Mysql2::Error: Field 'community_id' doesn't have a default value: INSERT INTO `notifications` (`content`, `link`, `created_at`, `updated_at`) VALUES ('👋 Welcome to Codidact! Take our tour to find out how this site works.', '/tour', '2020-08-25 18:14:58', '2020-08-25 18:14:58'))
and the function
def create_notification(content, link)
notification = Notification.create(content: content, link: link)
notifications << notification
end
Is Codadict designed to be connected to some larger community, and then get an id?
Ah. Good that we ruled that option out. :D Okay. Revert the change and add || RequestContext.community.nil?
to the end of the return-clause at the top. That could work. :)
That worked! There was a tiny issue with wanting to send an email, but the user seems to have been created okay anyway :)
...
(1.9ms) COMMIT
Devise::Mailer#confirmation_instructions: processed outbound mail in 4.6ms
Traceback (most recent call last):
1: from (irb):1
ArgumentError (No :access_key_id provided)
But I can at least get acknowledgement from the interface that my account exists!
It looks like you are using something called Devise, and there is @ArtOfCode- UK email address and a key (but still the error because no access key?) So I think we would either need to get that working, or to have an option to disable email confirmation (likely would be useful for more development / Docker setups).
This might be promising
# ==> Configuration for :confirmable
# A period that the user is allowed to access the website even without
# confirming their account. For instance, if set to 2.days, the user will be
# able to access the website for two days without confirming their account,
# access will be blocked just in the third day. Default is 0.days, meaning
# the user cannot access the website without confirming their account.
# config.allow_unconfirmed_access_for = 2.days
Yeah. That issue is known and happens, because no email is configured. As we require validation, it's also IMO status-bydesign.
You can update the user by setting confirmed_at to the current time. Something like user.update confirmed_at: DateTime.now
should work for the initial user setup. And you might want to set is_global_admin
to true, too.
Success!
So I'm logged in, and wondering what kinds of other actions an admin needs to do for setup? For example, when I try to create a post I get an error about tag sets not having a default value.
The function being called is this one in post.rb
def update_tag_associations
tags_cache.each do |tag_name|
tag = Tag.find_or_create_by name: tag_name, tag_set: category.tag_set
unless tags.include? tag
tags << tag
end
end
tags.each do |tag|
unless tags_cache.include? tag.name
tags.delete tag
end
end
end
with parent in posts_controller.rb - seems like the error is on @post.save (line 29)
def create
@category = Category.find(params[:category_id])
@post = Post.new(post_params.merge(category: @category, user: current_user,
post_type_id: params[:post][:post_type_id] || params[:post_type_id],
body: helpers.render_markdown(params[:post][:body_markdown])))
if @category.min_trust_level.present? && @category.min_trust_level > current_user.trust_level
@post.errors.add(:base, "You don't have a high enough trust level to post in the #{@category.name} category.")
render :new, status: 403
return
end
if @post.save
redirect_to helpers.generic_show_link(@post)
else
render :new, status: 400
end
end
Heh. I thought @ArtOfCode- had written something about that, but it was on a different post. :D
You need to go to the categories, edit them and choose a tag set (likely Main for Q&A and Meta for Meta). You might also want to go to /admin/setup to do some administrative setup stuff, including seeding tags.
I probably just missed it! Let me give those areas a quick look.
Yep that worked!
okay things are looking good, I've tested it again from start to finish, and works! I'm going to open a PR to discuss changes. This version is done for development, so likely in the PR we'd want to discuss how the user can set an environment variable for the docker-compose that would signal production. But if we do that, we'd also want to make sure the emails will work. It would also be okay to have this first PR provide the container build for development only. I'll repeat this when I open the PR.
Is it me, or is this still an issue when https://github.com/codidact/qpixel/blob/develop/docker/README.md is followed? I still got this with Docker for Mac:
@sbkg0002 You need to change the community record in the database to have a host field of 0.0.0.0:3000
, then it'll work
@sbkg0002 did you try using localhost instead of 0.0.0.0 meta address?
Thanks @artofcode-, but how?
Not much detail needed, I believe
:)
Wrapping this software up in a Docker container will surely make development, testing and deployment easier. At first glance, three containers are required: a Redis, a MySQL, and the last one for this app itself.
The Dockerfile would be pretty straightforward: Install necessary software from APT repository and RubyGems, then
ENTRYPOINT /usr/src/app/bin/rails
. A custom script to initialize the application by reading environment variables and generating the configuration files at the first start is also in need.With all those stuff ready, a
docker-compose.yml
should be easy to work out.The
Dockerfile
file from Charcoal-SE/metasmoke would be a good point to start at, although it's missing some best-practices for Docker.Ideas?