# Migrate a XenForo forum to Discourse

**URL:** https://meta.discourse.org/t/migrate-a-xenforo-forum-to-discourse/45232
**Category:** Sysadmins
**Tags:** how-to
**Created:** [June 4, 2016, 1:38am UTC](https://meta.discourse.org/t/migrate-a-xenforo-forum-to-discourse/45232 "2016-06-04T01:38:22Z")
**Posts on this page:** 20
**Page:** 1

<div class="post-metadata">

### Author: ![Cyb3r](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/cyb3r/32/96176_2.png) [@Cyb3r](https://meta.discourse.org/u/Cyb3r)
#### Post date: [June 4, 2016, 1:38am UTC](https://meta.discourse.org/t/migrate-a-xenforo-forum-to-discourse/45232/1 "2016-06-04T01:38:22Z")

</div>

Hey guys so after trying for a week or so I decided to import the database on docker app which I hoped it will succeed without any issues. TBH I got some issues at first but it turned to be all easy to solve.

Now I would recommend doing this only once before you deploy your production site, after importing everything take a Discourse backup, wipe everything out and install new Discourse instance then restore the imported db.

Ok let’s begin:

1. **First lets backup your old database from your old server, sign in to your Discourse server then:**

2. **After installing Discourse start the app:**

3. **Now lets pull the database backup from xenforo server:**

4. **Login to docker machine, install and start mysql:**

5. **Login to mysql and create new database:**

6. **Import your xenforo database into the new one:**

7. **Include the gem in discourse Gemfile:**

8. **Run bundle install:**

9. **Edit the importer script and change the following:**

10. **You are set to go now, run the importer:**

11. **If you get the error `'Peer authentication failed for user "discourse"'`** :

12. Edit the file `/etc/postgresql/9.5/main/pg_hba.conf`

13. change all ‘peer’ to ‘trust’ and save the file

14. restart postgres server: `service postgresql restart`

Run the importer again and this time it should work without any problem, be patient this might take a while based on your database size.

Hope this helps someone. 🙂

---

<div class="post-metadata">

### Author: ![RoldanLT](https://avatars.discourse-cdn.com/v4/letter/r/da6949/32.png) [@RoldanLT](https://meta.discourse.org/u/RoldanLT)
#### Post date: [July 14, 2018, 10:21pm UTC](https://meta.discourse.org/t/migrate-a-xenforo-forum-to-discourse/45232/9 "2018-07-14T22:21:54Z")

</div>

What are the list of XenForo Data covered on this import?  
I hope to import this list:

#### XenForo Page Nodes

- Pages

#### XenForo

- Profile Fields
- Member Groups
- Members
- Status Updates / Profile Comments
- Status Comments
- Private Messages
- Private Message Replies
- Attachments
- Member Ranks

#### XenForo Forums

- Forums
- Topics
- Posts
- Attachments

---

<div class="post-metadata">

### Author: ![RoldanLT](https://avatars.discourse-cdn.com/v4/letter/r/da6949/32.png) [@RoldanLT](https://meta.discourse.org/u/RoldanLT)
#### Post date: [July 31, 2018, 11:59pm UTC](https://meta.discourse.org/t/migrate-a-xenforo-forum-to-discourse/45232/10 "2018-07-31T23:59:56Z")

</div>

> [@Cyb3r](#):
>
> `bundle install --no-deployment`

Got this error:

```
# bundle install --no-deployment
Don't run Bundler as root. Bundler can ask for sudo if it is needed, and installing your bundle as root will break this application for all non-root users on this machine.
Your Gemfile has no gem server sources. If you need gems that are not already on your machine, add a line like this to your Gemfile:
source 'https://rubygems.org'
Could not find gem 'mysql2' in any of the gem sources listed in your Gemfile.

```

---

<div class="post-metadata">

### Author: ![RoldanLT](https://avatars.discourse-cdn.com/v4/letter/r/da6949/32.png) [@RoldanLT](https://meta.discourse.org/u/RoldanLT)
#### Post date: [August 1, 2018, 1:04am UTC](https://meta.discourse.org/t/migrate-a-xenforo-forum-to-discourse/45232/11 "2018-08-01T01:04:28Z")

</div>

Different Error now.

```
root@discourse-app:/var/www/discourse# RAILS_ENV=production bundle exec ruby script/import_scripts/xenforo.rb
No connection to db, unable to retrieve site settings! (normal when running db:create)
No connection to db, unable to retrieve site settings! (normal when running db:create)
No connection to db, unable to retrieve site settings! (normal when running db:create)
No connection to db, unable to retrieve site settings! (normal when running db:create)
No connection to db, unable to retrieve site settings! (normal when running db:create)
No connection to db, unable to retrieve site settings! (normal when running db:create)
Traceback (most recent call last):
	31: from script/import_scripts/xenforo.rb:3:in `<main>'
	30: from script/import_scripts/xenforo.rb:3:in `require'
	29: from /var/www/discourse/script/import_scripts/base.rb:20:in `<top (required)>'
	28: from /var/www/discourse/script/import_scripts/base.rb:544:in `<class:Base>'
	27: from /var/www/discourse/lib/discourse.rb:411:in `system_user'
	26: from /usr/local/lib/ruby/gems/2.5.0/gems/activerecord-5.2.0/lib/active_record/core.rb:196:in `find_by'
	25: from /usr/local/lib/ruby/gems/2.5.0/gems/activerecord-5.2.0/lib/active_record/core.rb:196:in `all?'
	24: from /usr/local/lib/ruby/gems/2.5.0/gems/activerecord-5.2.0/lib/active_record/core.rb:196:in `each'
	23: from /usr/local/lib/ruby/gems/2.5.0/gems/activerecord-5.2.0/lib/active_record/core.rb:196:in `block in find_by'
	22: from /usr/local/lib/ruby/gems/2.5.0/gems/activerecord-5.2.0/lib/active_record/model_schema.rb:336:in `columns_hash'
	21: from /usr/local/lib/ruby/gems/2.5.0/gems/activerecord-5.2.0/lib/active_record/model_schema.rb:456:in `load_schema'
	20: from /usr/local/lib/ruby/2.5.0/monitor.rb:226:in `mon_synchronize'
	19: from /usr/local/lib/ruby/gems/2.5.0/gems/activerecord-5.2.0/lib/active_record/model_schema.rb:459:in `block in load_schema'
	18: from /usr/local/lib/ruby/gems/2.5.0/gems/activerecord-5.2.0/lib/active_record/attribute_decorators.rb:51:in `load_schema!'
	17: from /usr/local/lib/ruby/gems/2.5.0/gems/activerecord-5.2.0/lib/active_record/attributes.rb:234:in `load_schema!'
	16: from /usr/local/lib/ruby/gems/2.5.0/gems/activerecord-5.2.0/lib/active_record/model_schema.rb:466:in `load_schema!'
	15: from /usr/local/lib/ruby/gems/2.5.0/gems/activerecord-5.2.0/lib/active_record/connection_handling.rb:90:in `connection'
	14: from /usr/local/lib/ruby/gems/2.5.0/gems/activerecord-5.2.0/lib/active_record/connection_handling.rb:118:in `retrieve_connection'
	13: from /usr/local/lib/ruby/gems/2.5.0/gems/activerecord-5.2.0/lib/active_record/connection_adapters/abstract/connection_pool.rb:1008:in `retrieve_connection'
	12: from /usr/local/lib/ruby/gems/2.5.0/gems/activerecord-5.2.0/lib/active_record/connection_adapters/abstract/connection_pool.rb:380:in `connection'
	11: from /usr/local/lib/ruby/gems/2.5.0/gems/activerecord-5.2.0/lib/active_record/connection_adapters/abstract/connection_pool.rb:521:in `checkout'
	10: from /usr/local/lib/ruby/gems/2.5.0/gems/activerecord-5.2.0/lib/active_record/connection_adapters/abstract/connection_pool.rb:793:in `acquire_connection'
	 9: from /usr/local/lib/ruby/gems/2.5.0/gems/activerecord-5.2.0/lib/active_record/connection_adapters/abstract/connection_pool.rb:832:in `try_to_checkout_new_connection'
	 8: from /usr/local/lib/ruby/gems/2.5.0/gems/activerecord-5.2.0/lib/active_record/connection_adapters/abstract/connection_pool.rb:853:in `checkout_new_connection'
	 7: from /usr/local/lib/ruby/gems/2.5.0/gems/activerecord-5.2.0/lib/active_record/connection_adapters/abstract/connection_pool.rb:809:in `new_connection'
	 6: from /usr/local/lib/ruby/gems/2.5.0/gems/activerecord-5.2.0/lib/active_record/connection_adapters/postgresql_adapter.rb:40:in `postgresql_connection'
	 5: from /usr/local/lib/ruby/gems/2.5.0/gems/activerecord-5.2.0/lib/active_record/connection_adapters/postgresql_adapter.rb:40:in `new'
	 4: from /usr/local/lib/ruby/gems/2.5.0/gems/activerecord-5.2.0/lib/active_record/connection_adapters/postgresql_adapter.rb:215:in `initialize'
	 3: from /usr/local/lib/ruby/gems/2.5.0/gems/activerecord-5.2.0/lib/active_record/connection_adapters/postgresql_adapter.rb:684:in `connect'
	 2: from /usr/local/lib/ruby/gems/2.5.0/gems/pg-1.0.0/lib/pg.rb:56:in `connect'
	 1: from /usr/local/lib/ruby/gems/2.5.0/gems/pg-1.0.0/lib/pg.rb:56:in `new'
/usr/local/lib/ruby/gems/2.5.0/gems/pg-1.0.0/lib/pg.rb:56:in `initialize': FATAL: Peer authentication failed for user "discourse" (PG::ConnectionBad)

```

---

<div class="post-metadata">

### Author: ![RoldanLT](https://avatars.discourse-cdn.com/v4/letter/r/da6949/32.png) [@RoldanLT](https://meta.discourse.org/u/RoldanLT)
#### Post date: [August 1, 2018, 1:16am UTC](https://meta.discourse.org/t/migrate-a-xenforo-forum-to-discourse/45232/12 "2018-08-01T01:16:48Z")

</div>

Yay no idea how long this will take 😃

 ![image](https://global.discourse-cdn.com/meta/original/3X/a/6/a69cb452881498ae8b502c2be256b2cbb6a26253.png)

---

<div class="post-metadata">

### Author: ![RoldanLT](https://avatars.discourse-cdn.com/v4/letter/r/da6949/32.png) [@RoldanLT](https://meta.discourse.org/u/RoldanLT)
#### Post date: [August 1, 2018, 2:46am UTC](https://meta.discourse.org/t/migrate-a-xenforo-forum-to-discourse/45232/13 "2018-08-01T02:46:05Z")

</div>

> [@Cyb3r](#):
>
> change all ‘peer’ to ‘trust’ and save the file

This is correct right?

 ![image](https://global.discourse-cdn.com/meta/original/3X/7/5/75ba7a545ca348af2be65db436dabb0bf872ecdf.png)

---

<div class="post-metadata">

### Author: ![RoldanLT](https://avatars.discourse-cdn.com/v4/letter/r/da6949/32.png) [@RoldanLT](https://meta.discourse.org/u/RoldanLT)
#### Post date: [August 1, 2018, 2:54am UTC](https://meta.discourse.org/t/migrate-a-xenforo-forum-to-discourse/45232/14 "2018-08-01T02:54:36Z")

</div>

> [@Cyb3r](#):
>
> Include the gem in discourse Gemfile:

Guide needs an update I think.  
Before running this, directory must be within /var/www/discourse/.  
`cd /var/www/discourse/`

---

<div class="post-metadata">

### Author: ![Canapin](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/canapin/32/119591_2.png) [@Canapin](https://meta.discourse.org/u/Canapin)
#### Post date: [May 24, 2023, 12:33pm UTC](https://meta.discourse.org/t/migrate-a-xenforo-forum-to-discourse/45232/15 "2023-05-24T12:33:15Z")

</div>

3 posts were split to a new topic: [XenForo import script imported banned users and soft-deleted topics and posts](https://meta.discourse.org/t/xenforo-import-script-imported-banned-users-and-soft-deleted-topics-and-posts/266055)

---

<div class="post-metadata">

### Author: ![codinghorror](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/codinghorror/32/110067_2.png) [@codinghorror](https://meta.discourse.org/u/codinghorror)
#### Post date: [July 17, 2019, 9:23am UTC](https://meta.discourse.org/t/migrate-a-xenforo-forum-to-discourse/45232/18 "2019-07-17T09:23:35Z")

</div>

8 posts were split to a new topic: [Help migrating Xenforo](https://meta.discourse.org/t/help-migrating-xenforo/123167)

---

<div class="post-metadata">

### Author: ![Canapin](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/canapin/32/119591_2.png) [@Canapin](https://meta.discourse.org/u/Canapin)
#### Post date: [May 24, 2023, 12:35pm UTC](https://meta.discourse.org/t/migrate-a-xenforo-forum-to-discourse/45232/19 "2023-05-24T12:35:53Z")

</div>

14 posts were split to a new topic: [Issues while importing attachments from XenForo](https://meta.discourse.org/t/issues-while-importing-attachments-from-xenforo/266056)

---

<div class="post-metadata">

### Author: ![Canapin](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/canapin/32/119591_2.png) [@Canapin](https://meta.discourse.org/u/Canapin)
#### Post date: [May 24, 2023, 12:55pm UTC](https://meta.discourse.org/t/migrate-a-xenforo-forum-to-discourse/45232/37 "2023-05-24T12:55:59Z")

</div>

5 posts were split to a new topic: [Troubles moving from XenForo to Discourse](https://meta.discourse.org/t/troubles-moving-from-xenforo-to-discourse/266060)

---

<div class="post-metadata">

### Author: ![Canapin](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/canapin/32/119591_2.png) [@Canapin](https://meta.discourse.org/u/Canapin)
#### Post date: [May 24, 2023, 12:57pm UTC](https://meta.discourse.org/t/migrate-a-xenforo-forum-to-discourse/45232/42 "2023-05-24T12:57:25Z")

</div>

A post was merged into an existing topic: [Troubles moving from XenForo to Discourse](https://meta.discourse.org/t/troubles-moving-from-xenforo-to-discourse/266060/6)

---

<div class="post-metadata">

### Author: ![R\_X](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/r_x/32/142155_2.png) [@R\_X](https://meta.discourse.org/u/R_X)
#### Post date: [August 14, 2020, 1:27pm UTC](https://meta.discourse.org/t/migrate-a-xenforo-forum-to-discourse/45232/46 "2020-08-14T13:27:52Z")

</div>

Just gonna ask you guys why you move from xenforo to discourse? Im just started a forum a week now and i’ve seem xenforo runned websites and im impressed because of their plugins including pointing system. I just wanted the cons or reasons of moving. Thankyou

---

<div class="post-metadata">

### Author: ![Jack51](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/jack51/32/201652_2.png) [@Jack51](https://meta.discourse.org/u/Jack51)
#### Post date: [January 2, 2021, 6:25pm UTC](https://meta.discourse.org/t/migrate-a-xenforo-forum-to-discourse/45232/49 "2021-01-02T18:25:14Z")

</div>

Just finished up a Xenforo → Discourse migration of a million post board on a Digital Ocean droplet. Here’s what worked for me command by command (very similar to what also just did on a different vbulletin board).

Recommend minimum 4 vCPU/8GB for import.

Thanks to everyone in this thread for helping me get through these migrations, definingly been a fun few days reading and rereading..

#### 1 - Install Digital Ocean Discourse 1-click droplet

#### 2 - Finish discourse install through SSH by following prompts

```
Open SSH console
root
(yourrootpassword)
(enter)
(yourdomain).com
etc

```

#### 3 - Login to SFTP

```
sftp root@XXX.XXX.XX.XX
y (if asked for confirmation)
yes
(yourrootpassword)
put db.sql /var/discourse/shared/standalone/db.sql

```

#### 4 - Login to Website to setup Admin account

#### 5 - Login to SSH - Begin Process

```
ssh root@XXX.XXX.XX.XX
cd /var/discourse
./launcher start app
docker exec -it app bash
sudo apt-get update
sudo apt-get upgrade
y

```

#### 6 - Install MariaDB (replacement for mysql)

```
apt-get update && apt-get install mariadb-server-10.3 libmariadbd-dev
y

```

#### 7 - Mysql Database Setup

```
service mysql start
mysql -u root -p
password
create database import_db;
exit;

```

#### 8 - Import Dump → Mysql Database Transfer\*\*

```
mysql -u root -p import_db < /shared/db.sql
password

```

#### 9 - GEM File

```
echo "gem 'mysql2'" >>Gemfile
echo "gem 'mysql2', require: false" >> /var/www/discourse/Gemfile
echo "gem 'php_serialize', require: false" >> /var/www/discourse/Gemfile
cd /var/www/discourse
su discourse -c 'bundle install --no-deployment --without test --without development --path vendor/bundle'
(ignore red text result)

```

#### 10 - Configure install script

```
vi /var/www/discourse/script/import_scripts/xenforo.rb

---Make edits to text file as needed for db name/password, prefix, etc---

(esc)
:wq

```

#### 11 - Bundle Config

```
bundle config set path 'vendor/bundle'
bundle config set without 'development:test'
bundle config unset deployment
su discourse -c 'bundle install'

```

#### 12 - Mysql config (may be possible to do this with previous)

```
mysql --version
sudo mysql -u root -p
password
ALTER USER 'root'@'localhost' IDENTIFIED BY 'password';
FLUSH PRIVILEGES;
exit

```

#### 13 - Install Script

```
su discourse -c 'bundle exec ruby script/import_scripts/xenforo.rb'

```

---

<div class="post-metadata">

### Author: ![Timelord](https://avatars.discourse-cdn.com/v4/letter/t/ba9def/32.png) [@Timelord](https://meta.discourse.org/u/Timelord)
#### Post date: [January 4, 2021, 6:45pm UTC](https://meta.discourse.org/t/migrate-a-xenforo-forum-to-discourse/45232/50 "2021-01-04T18:45:44Z")

</div>

> [@Jack51](#):
>
> `vi /var/www/discourse/script/import_scripts/xenforo.rb`

I am in the process of trying to get this migration complete, however it seems to be throwing an error with the attachments.

```plaintext
RAILS_ENV=production bundle exec ruby script/import_scripts/xenforo.rb
Loading existing groups...
Loading existing users...
Loading existing categories...
Loading existing posts...
Loading existing topics...

creating users
Skipping 407 already imported users

importing categories...
       12 / 12 (100.0%) [344731 items/min]
creating topics and posts
        2 / 4554 ( 0.0%) [17724 items/min] Traceback (most recent call last):
        18: from script/import_scripts/xenforo.rb:396:in `<main>'
        17: from /var/www/discourse/script/import_scripts/base.rb:47:in `perform'
        16: from script/import_scripts/xenforo.rb:32:in `execute'
        15: from script/import_scripts/xenforo.rb:174:in `import_posts'
        14: from /var/www/discourse/script/import_scripts/base.rb:866:in `batches'
        13: from /var/www/discourse/script/import_scripts/base.rb:866:in `loop'
        12: from /var/www/discourse/script/import_scripts/base.rb:867:in `block in batches'
        11: from script/import_scripts/xenforo.rb:180:in `block in import_posts'
        10: from /var/www/discourse/script/import_scripts/base.rb:508:in `create_posts'
         9: from /var/www/discourse/script/import_scripts/base.rb:508:in `each'
         8: from /var/www/discourse/script/import_scripts/base.rb:509:in `block in create_posts'
         7: from script/import_scripts/xenforo.rb:186:in `block (2 levels) in import_posts'
         6: from script/import_scripts/xenforo.rb:315:in `process_xenforo_post'
         5: from script/import_scripts/xenforo.rb:324:in `process_xf_attachments'
         4: from /usr/local/lib/ruby/2.7.0/set.rb:328:in `each'
         3: from /usr/local/lib/ruby/2.7.0/set.rb:328:in `each_key'
         2: from script/import_scripts/xenforo.rb:326:in `block in process_xf_attachments'
         1: from /var/www/discourse/vendor/bundle/ruby/2.7.0/gems/activesupport-6.0.3.3/lib/active_support/core_ext/string/filters.rb:22:in `squish!'
/var/www/discourse/vendor/bundle/ruby/2.7.0/gems/activesupport-6.0.3.3/lib/active_support/core_ext/string/filters.rb:22:in `gsub!': can't modify frozen String: "\\t\\tSELECT a.attachment_id, a.data_id, d.fil\n\\t\\tFROM xf_attachment AS a\\n\\t\\tINNER JOIN xf_attachment_data d ON a.data_id = d.data_id\\n\\t\\tWHERE attachment_id = 13\\n" (FrozenError)

Does anyone have any thoughts on what could be going on here? What is the "FrozenError"?
```

---

<div class="post-metadata">

### Author: ![Timelord](https://avatars.discourse-cdn.com/v4/letter/t/ba9def/32.png) [@Timelord](https://meta.discourse.org/u/Timelord)
#### Post date: [January 4, 2021, 6:52pm UTC](https://meta.discourse.org/t/migrate-a-xenforo-forum-to-discourse/45232/51 "2021-01-04T18:52:57Z")

</div>

It looks like I had to edit the xenforo.rb file and change

`# frozen_string_literal: true`

to

`# frozen_string_literal: false`

---

<div class="post-metadata">

### Author: ![AstonJ](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/astonj/32/215041_2.png) [@AstonJ](https://meta.discourse.org/u/AstonJ)
#### Post date: [January 22, 2021, 3:55am UTC](https://meta.discourse.org/t/migrate-a-xenforo-forum-to-discourse/45232/52 "2021-01-22T03:55:36Z")

</div>

Thanks for writing this guide!

Does the importer also import avatars and attachments? Do I simply copy them to the `/tmp/attachments` folder?

---

<div class="post-metadata">

### Author: ![justin](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/justin/32/157614_2.png) [@justin](https://meta.discourse.org/u/justin)
#### Post date: [January 22, 2021, 4:19pm UTC](https://meta.discourse.org/t/migrate-a-xenforo-forum-to-discourse/45232/53 "2021-01-22T16:19:28Z")

</div>

From a quick look at the importer, it appears it only imports uploads to posts. Avatar support would need to be added.

---

<div class="post-metadata">

### Author: ![Timelord](https://avatars.discourse-cdn.com/v4/letter/t/ba9def/32.png) [@Timelord](https://meta.discourse.org/u/Timelord)
#### Post date: [January 24, 2021, 4:56pm UTC](https://meta.discourse.org/t/migrate-a-xenforo-forum-to-discourse/45232/54 "2021-01-24T16:56:27Z")

</div>

Can confirm. It only imports uploads. Avatars are not included. I just completed a Xenforo migration last week.

---

<div class="post-metadata">

### Author: ![RoldanLT](https://avatars.discourse-cdn.com/v4/letter/r/da6949/32.png) [@RoldanLT](https://meta.discourse.org/u/RoldanLT)
#### Post date: [January 24, 2021, 4:57pm UTC](https://meta.discourse.org/t/migrate-a-xenforo-forum-to-discourse/45232/55 "2021-01-24T16:57:19Z")

</div>

Board size?  
Post/threads/members.  
Congrats 🙂

[Next page](https://meta.discourse.org/t/migrate-a-xenforo-forum-to-discourse/45232.md?page=2)
